@middy/http-multipart-body-parser
Advanced tools
Comparing version 1.5.2 to 2.0.0-alpha.0
@@ -1,187 +0,206 @@ | ||
const { invoke } = require('../../test-helpers') | ||
const middy = require('../../core') | ||
const httpMultipartBodyParser = require('../') | ||
const test = require('ava') | ||
const middy = require('../../core/index.js') | ||
const httpMultipartBodyParser = require('../index.js') | ||
describe('📦 Middleware Multipart Form Data Body Parser', () => { | ||
test('It should parse a non-file field from a multipart/form-data request', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
test('It should parse a non-file field from a multipart/form-data request', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// invokes the handler | ||
// Base64 encoded form data with field 'foo' of value 'bar' | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb28iDQoNCmJhcg0KLS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTS0t', | ||
isBase64Encoded: true | ||
} | ||
const response = await invoke(handler, event) | ||
// invokes the handler | ||
// Base64 encoded form data with field 'foo' of value 'bar' | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb28iDQoNCmJhcg0KLS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTS0t', | ||
isBase64Encoded: true | ||
} | ||
const response = await handler(event) | ||
expect(response).toEqual({ foo: 'bar' }) | ||
t.deepEqual(response, { foo: 'bar' }) | ||
}) | ||
test('parseMultipartData should resolve with valid data', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('parseMultipartData should resolve with valid data', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb28iDQoNCmJhcg0KLS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTS0t', | ||
isBase64Encoded: true | ||
} | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb28iDQoNCmJhcg0KLS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTS0t', | ||
isBase64Encoded: true | ||
} | ||
const response = await handler(event) | ||
t.deepEqual(response, { foo: 'bar' }) | ||
}) | ||
const response = await invoke(handler, event) | ||
expect(response).toEqual({ foo: 'bar' }) | ||
test('It should parse a file field from a multipart/form-data request', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It should parse a file field from a multipart/form-data request', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// Base64 encoded form data with a file with fieldname 'attachment', filename 'test.txt', and contents 'hello world!' | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=------------------------4f0e69e6c2513684' | ||
}, | ||
body: 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS00ZjBlNjllNmMyNTEzNjg0DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImF0dGFjaG1lbnQiOyBmaWxlbmFtZT0idGVzdC50eHQiDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCg0KaGVsbG8gd29ybGQhCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS00ZjBlNjllNmMyNTEzNjg0LS0NCg==', | ||
isBase64Encoded: true | ||
} | ||
// Base64 encoded form data with a file with fieldname 'attachment', filename 'test.txt', and contents 'hello world!' | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=------------------------4f0e69e6c2513684' | ||
}, | ||
body: 'LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS00ZjBlNjllNmMyNTEzNjg0DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImF0dGFjaG1lbnQiOyBmaWxlbmFtZT0idGVzdC50eHQiDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW4NCg0KaGVsbG8gd29ybGQhCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS00ZjBlNjllNmMyNTEzNjg0LS0NCg==', | ||
isBase64Encoded: true | ||
} | ||
const response = await handler(event) | ||
const response = await invoke(handler, event) | ||
expect(Object.keys(response)).toContain('attachment') | ||
expect(Object.keys(response.attachment)).toContain('content') | ||
t.not(response.attachment, undefined) | ||
t.not(response.attachment.content, undefined) | ||
}) | ||
// | ||
test('It should handle invalid form data as an UnprocessableEntity', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
// | ||
test('It should handle invalid form data as an UnprocessableEntity', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=------WebKitFormBoundaryfdmza9FgfefwkQzA' | ||
}, | ||
body: null, | ||
isBase64Encoded: true | ||
} | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=------WebKitFormBoundaryfdmza9FgfefwkQzA' | ||
}, | ||
body: null, | ||
isBase64Encoded: true | ||
} | ||
try { | ||
await invoke(handler, event) | ||
} catch (e) { | ||
expect(e.message).toEqual('Invalid or malformed multipart/form-data was provided') | ||
} | ||
try { | ||
await handler(event) | ||
} catch (e) { | ||
t.is(e.message, 'Invalid or malformed multipart/form-data was provided') | ||
} | ||
}) | ||
test('It should handle more invalid form data as an UnprocessableEntity', async (t) => { | ||
// Body contains LF instead of CRLF line endings, which cant be processed | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It should handle more invalid form data as an UnprocessableEntity', async () => { | ||
// Body contains LF instead of CRLF line endings, which cant be processed | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=', | ||
isBase64Encoded: true | ||
} | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=', | ||
isBase64Encoded: true | ||
} | ||
try { | ||
await handler(event) | ||
} catch (e) { | ||
t.is(e.message, 'Invalid or malformed multipart/form-data was provided') | ||
} | ||
}) | ||
try { | ||
await invoke(handler, event) | ||
} catch (e) { | ||
expect(e.message).toEqual('Invalid or malformed multipart/form-data was provided') | ||
} | ||
test('It shouldn\'t process the body if no headers are passed', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It shouldn\'t process the body if no headers are passed', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// invokes the handler | ||
const event = { | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
// invokes the handler | ||
const event = { | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
const response = await handler(event) | ||
const response = await invoke(handler, event) | ||
t.is(response, 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
}) | ||
expect(response).toEqual('LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
test('It shouldn\'t process the body if the content type is not multipart/form-data', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It shouldn\'t process the body if the content type is not multipart/form-data', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
const response = await handler(event) | ||
t.is(response, 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
}) | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
'content-type': 'application/json' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
const response = await invoke(handler, event) | ||
expect(response).toEqual('LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
test('It shouldn\'t process the body if headers are passed without content type', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It shouldn\'t process the body if headers are passed without content type', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
accept: 'application/json' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
// invokes the handler | ||
const event = { | ||
headers: { | ||
accept: 'application/json' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=' | ||
} | ||
const response = await handler(event) | ||
t.is(response, 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
}) | ||
const response = await invoke(handler, event) | ||
expect(response).toEqual('LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvbyIKCmJhcgotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNLS0=') | ||
test('It should parse an array from a multipart/form-data request (base64)', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
test('It should parse an array from a multipart/form-data request', async () => { | ||
const handler = middy((event, context, cb) => { | ||
cb(null, event.body) // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
handler.use(httpMultipartBodyParser()) | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb29bXSINCg0Kb25lDQotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvb1tdIg0KDQp0d28NCi0tLS0tLVdlYktpdEZvcm1Cb3VuZGFyeXBwc1FFd2YyQlZKZUNlME0tLQ==', | ||
isBase64Encoded: true | ||
} | ||
const response = await handler(event) | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: 'LS0tLS0tV2ViS2l0Rm9ybUJvdW5kYXJ5cHBzUUV3ZjJCVkplQ2UwTQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJmb29bXSINCg0Kb25lDQotLS0tLS1XZWJLaXRGb3JtQm91bmRhcnlwcHNRRXdmMkJWSmVDZTBNDQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImZvb1tdIg0KDQp0d28NCi0tLS0tLVdlYktpdEZvcm1Cb3VuZGFyeXBwc1FFd2YyQlZKZUNlME0tLQ==', | ||
isBase64Encoded: true | ||
} | ||
const response = await invoke(handler, event) | ||
t.not(response.foo, undefined) | ||
t.is(response.foo.length, 2) | ||
}) | ||
expect(Object.keys(response)).toContain('foo') | ||
expect(response.foo.length).toEqual(2) | ||
test('It should parse an array from a multipart/form-data request (binary)', async (t) => { | ||
const handler = middy((event, context) => { | ||
return event.body // propagates the body as a response | ||
}) | ||
handler.use(httpMultipartBodyParser()) | ||
const event = { | ||
headers: { | ||
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryppsQEwf2BVJeCe0M' | ||
}, | ||
body: '', | ||
isBase64Encoded: false | ||
} | ||
const response = await handler(event) | ||
// TODO add in better test for binary | ||
t.deepEqual(response, { }) | ||
}) | ||
134
index.js
@@ -1,80 +0,86 @@ | ||
const BusBoy = require('busboy') | ||
const contentTypeLib = require('content-type') | ||
const createError = require('http-errors') | ||
const BusBoy = require('busboy'); | ||
module.exports = opts => { | ||
const contentTypeLib = require('content-type'); | ||
const createError = require('http-errors'); | ||
module.exports = (opts = {}) => { | ||
const defaults = { | ||
// busboy options as per documentation: https://www.npmjs.com/package/busboy#busboy-methods | ||
busboy: {} | ||
} | ||
}; | ||
const options = { ...defaults, | ||
...opts | ||
}; | ||
const options = Object.assign({}, defaults, opts) | ||
const httpMultipartBodyParserBefore = async handler => { | ||
const { | ||
headers | ||
} = handler.event; | ||
return { | ||
before: (handler, next) => { | ||
const { headers } = handler.event | ||
if (!headers) { | ||
return next() | ||
} | ||
if (!headers) { | ||
return; | ||
} | ||
const contentType = headers['Content-Type'] || headers['content-type'] | ||
if (contentType) { | ||
const { type } = contentTypeLib.parse(contentType) | ||
if (type !== 'multipart/form-data') { | ||
return next() | ||
} | ||
const contentType = headers?.['Content-Type'] ?? headers?.['content-type']; | ||
return parseMultipartData(handler.event, options.busboy) | ||
.then(multipartData => { handler.event.body = multipartData }) | ||
.catch(_ => { | ||
throw new createError.UnprocessableEntity('Invalid or malformed multipart/form-data was provided') | ||
}) | ||
} else { | ||
return next() | ||
if (contentType) { | ||
const { | ||
type | ||
} = contentTypeLib.parse(contentType); | ||
if (type !== 'multipart/form-data') { | ||
return; | ||
} | ||
return parseMultipartData(handler.event, options.busboy).then(multipartData => { | ||
handler.event.body = multipartData; | ||
}).catch(_ => { | ||
throw new createError.UnprocessableEntity('Invalid or malformed multipart/form-data was provided'); | ||
}); | ||
} | ||
} | ||
} | ||
}; | ||
return { | ||
before: httpMultipartBodyParserBefore | ||
}; | ||
}; | ||
const parseMultipartData = (event, options) => { | ||
const multipartData = {} | ||
const bb = BusBoy(Object.assign({}, options, { headers: event.headers })) | ||
const multipartData = {}; | ||
const bb = BusBoy({ ...options, | ||
headers: event.headers | ||
}); | ||
return new Promise((resolve, reject) => { | ||
bb | ||
.on('file', (fieldname, file, filename, encoding, mimetype) => { | ||
const attachment = { | ||
filename, | ||
mimetype, | ||
encoding | ||
} | ||
bb.on('file', (fieldname, file, filename, encoding, mimetype) => { | ||
const attachment = { | ||
filename, | ||
mimetype, | ||
encoding | ||
}; | ||
const chunks = []; | ||
file.on('data', data => { | ||
chunks.push(data); | ||
}); | ||
file.on('end', () => { | ||
attachment.truncated = file.truncated; | ||
attachment.content = Buffer.concat(chunks); | ||
multipartData[fieldname] = attachment; | ||
}); | ||
}).on('field', (fieldname, value) => { | ||
const matches = fieldname.match(/(.+)\[(.*)]$/); | ||
const chunks = [] | ||
file.on('data', data => { | ||
chunks.push(data) | ||
}) | ||
file.on('end', () => { | ||
attachment.truncated = file.truncated | ||
attachment.content = Buffer.concat(chunks) | ||
multipartData[fieldname] = attachment | ||
}) | ||
}) | ||
.on('field', (fieldname, value) => { | ||
const matches = fieldname.match(/(.+)\[(.*)]$/) | ||
if (!matches) { | ||
multipartData[fieldname] = value | ||
} else { | ||
if (!multipartData[matches[1]]) { | ||
multipartData[matches[1]] = [] | ||
} | ||
multipartData[matches[1]].push(value) | ||
if (!matches) { | ||
multipartData[fieldname] = value; | ||
} else { | ||
if (!multipartData[matches[1]]) { | ||
multipartData[matches[1]] = []; | ||
} | ||
}) | ||
.on('finish', () => resolve(multipartData)) | ||
.on('error', err => reject(err)) | ||
bb.write(event.body, event.isBase64Encoded ? 'base64' : 'binary') | ||
bb.end() | ||
}) | ||
} | ||
multipartData[matches[1]].push(value); | ||
} | ||
}).on('finish', () => resolve(multipartData)).on('error', err => reject(err)); | ||
bb.write(event.body, event.isBase64Encoded ? 'base64' : 'binary'); | ||
bb.end(); | ||
}); | ||
}; |
{ | ||
"name": "@middy/http-multipart-body-parser", | ||
"version": "1.5.2", | ||
"version": "2.0.0-alpha.0", | ||
"description": "Http event normalizer middleware for the middy framework", | ||
"type": "commonjs", | ||
"engines": { | ||
"node": ">=10" | ||
"node": ">=14" | ||
}, | ||
@@ -12,5 +13,7 @@ "engineStrict": true, | ||
}, | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"scripts": { | ||
"test": "npm run test:typings && npm run test:unit", | ||
"test:unit": "jest", | ||
"test:unit": "ava", | ||
"test:typings": "typings-tester --config tsconfig.json index.d.ts" | ||
@@ -37,3 +40,4 @@ }, | ||
"type": "git", | ||
"url": "git+https://github.com/middyjs/middy.git" | ||
"url": "github:middyjs/middy", | ||
"directory": "packages/http-multipart-body-parser" | ||
}, | ||
@@ -44,15 +48,8 @@ "bugs": { | ||
"homepage": "https://github.com/middyjs/middy#readme", | ||
"peerDependencies": { | ||
"@middy/core": ">=1.0.0-alpha" | ||
}, | ||
"dependencies": { | ||
"busboy": "0.3.1", | ||
"content-type": "1.0.4", | ||
"http-errors": "^1.7.3" | ||
"http-errors": "1.8.0" | ||
}, | ||
"devDependencies": { | ||
"@middy/core": "^1.5.2", | ||
"es6-promisify": "^6.0.2" | ||
}, | ||
"gitHead": "f77cb5e1fc2c529f4fe74efa8a9fb105373b0723" | ||
"gitHead": "e047c0d3db00aa11b39f2d3e193458ea021a58a0" | ||
} |
# Middy http-multipart-body-parser middleware | ||
<div align="center"> | ||
<img alt="Middy logo" src="https://raw.githubusercontent.com/middyjs/middy/master/img/middy-logo.png"/> | ||
<img alt="Middy logo" src="https://raw.githubusercontent.com/middyjs/middy/master/docs/img/middy-logo.png"/> | ||
</div> | ||
@@ -22,5 +22,2 @@ | ||
</a> | ||
<a href="https://greenkeeper.io/"> | ||
<img src="https://badges.greenkeeper.io/middyjs/middy.svg" alt="Greenkeeper badge" style="max-width:100%;"> | ||
</a> | ||
<a href="https://gitter.im/middyjs/Lobby"> | ||
@@ -62,6 +59,6 @@ <img src="https://badges.gitter.im/gitterHQ/gitter.svg" alt="Chat on Gitter" style="max-width:100%;"> | ||
```javascript | ||
const middy = require('@middy/core') | ||
const { httpMultipartBodyParser } = require('@middy/http-multipart-body-parser') | ||
const handler = middy((event, context, cb) => { | ||
cb(null, {}) | ||
import middy from '@middy/core' | ||
import { httpMultipartBodyParser } from '@middy/http-multipart-body-parser' | ||
const handler = middy((event, context) => { | ||
return {} | ||
}) | ||
@@ -78,3 +75,3 @@ handler.use(httpMultipartBodyParser()) | ||
handler(event, {}, (_, body) => { | ||
expect(body).toEqual({ foo: 'bar' }) | ||
t.is(body,{ foo: 'bar' }) | ||
}) | ||
@@ -95,3 +92,3 @@ ``` | ||
Licensed under [MIT License](LICENSE). Copyright (c) 2017-2018 Luciano Mammino and the [Middy team](https://github.com/middyjs/middy/graphs/contributors). | ||
Licensed under [MIT License](LICENSE). Copyright (c) 2017-2021 Luciano Mammino, will Farrell, and the [Middy team](https://github.com/middyjs/middy/graphs/contributors). | ||
@@ -98,0 +95,0 @@ <a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fmiddyjs%2Fmiddy?ref=badge_large"> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3
0
246
16827
6
1
95
2
+ Addedhttp-errors@1.8.0(transitive)
+ Addedtoidentifier@1.0.0(transitive)
- Removed@datastream/core@0.0.38(transitive)
- Removed@middy/core@5.5.1(transitive)
- Removedabort-controller@3.0.0(transitive)
- Removedbase64-js@1.5.1(transitive)
- Removedbuffer@6.0.3(transitive)
- Removedcloneable-readable@3.0.0(transitive)
- Removedevent-target-shim@5.0.1(transitive)
- Removedevents@3.3.0(transitive)
- Removedhttp-errors@1.8.1(transitive)
- Removedieee754@1.2.1(transitive)
- Removedprocess@0.11.10(transitive)
- Removedreadable-stream@4.5.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedtoidentifier@1.0.1(transitive)
Updatedhttp-errors@1.8.0