@middy/http-multipart-body-parser 5.1.0 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +103 -89
  2. package/package.json +4 -4
package/index.js CHANGED
@@ -1,93 +1,107 @@
1
- import BusBoy from '@fastify/busboy';
2
- import { createError } from '@middy/util';
3
- const mimePattern = /^multipart\/form-data(;.*)?$/;
4
- const fieldnamePattern = /(.+)\[(.*)]$/;
1
+ import BusBoy from '@fastify/busboy'
2
+ import { createError } from '@middy/util'
3
+
4
+ const mimePattern = /^multipart\/form-data(;.*)?$/
5
+ const fieldnamePattern = /(.+)\[(.*)]$/
6
+
5
7
  const defaults = {
6
- busboy: {},
7
- charset: 'utf8',
8
- disableContentTypeError: false
9
- };
10
- const httpMultipartBodyParserMiddleware = (opts = {})=>{
11
- const options = {
12
- ...defaults,
13
- ...opts
14
- };
15
- const httpMultipartBodyParserMiddlewareBefore = async (request)=>{
16
- const { headers } = request.event;
17
- const contentType = headers?.['Content-Type'] ?? headers?.['content-type'];
18
- if (!mimePattern.test(contentType)) {
19
- if (options.disableContentTypeError) {
20
- return;
21
- }
22
- throw createError(415, 'Unsupported Media Type', {
23
- cause: {
24
- package: '@middy/multipart-body-parser',
25
- data: contentType
26
- }
27
- });
8
+ // busboy options as per documentation: https://www.npmjs.com/package/busboy#busboy-methods
9
+ busboy: {},
10
+ charset: 'utf8',
11
+ disableContentTypeError: false
12
+ }
13
+
14
+ const httpMultipartBodyParserMiddleware = (opts = {}) => {
15
+ const options = { ...defaults, ...opts }
16
+
17
+ const httpMultipartBodyParserMiddlewareBefore = async (request) => {
18
+ const { headers } = request.event
19
+
20
+ const contentType = headers?.['Content-Type'] ?? headers?.['content-type']
21
+
22
+ if (!mimePattern.test(contentType)) {
23
+ if (options.disableContentTypeError) {
24
+ return
25
+ }
26
+ throw createError(415, 'Unsupported Media Type', {
27
+ cause: { package: '@middy/multipart-body-parser', data: contentType }
28
+ })
29
+ }
30
+
31
+ return parseMultipartData(request.event, options)
32
+ .then((multipartData) => {
33
+ // request.event.rawBody = body
34
+ request.event.body = multipartData
35
+ })
36
+ .catch((err) => {
37
+ // UnprocessableEntity
38
+ throw createError(
39
+ 415,
40
+ 'Invalid or malformed multipart/form-data was provided',
41
+ { cause: { package: '@middy/multipart-body-parser', data: err } }
42
+ )
43
+ })
44
+ }
45
+
46
+ return {
47
+ before: httpMultipartBodyParserMiddlewareBefore
48
+ }
49
+ }
50
+
51
+ const parseMultipartData = (event, options) => {
52
+ const multipartData = {}
53
+ const charset = event.isBase64Encoded ? 'base64' : options.charset
54
+ // header must be lowercase (content-type)
55
+ const busboy = BusBoy({
56
+ ...options.busboy,
57
+ headers: {
58
+ 'content-type':
59
+ event.headers?.['Content-Type'] ?? event.headers?.['content-type']
60
+ }
61
+ })
62
+
63
+ return new Promise((resolve, reject) => {
64
+ busboy
65
+ .on('file', (fieldname, file, info) => {
66
+ const { filename, encoding, mimeType: mimetype } = info
67
+ const attachment = {
68
+ filename,
69
+ mimetype,
70
+ encoding
28
71
  }
29
- return parseMultipartData(request.event, options).then((multipartData)=>{
30
- request.event.body = multipartData;
31
- }).catch((err)=>{
32
- throw createError(415, 'Invalid or malformed multipart/form-data was provided', {
33
- cause: {
34
- package: '@middy/multipart-body-parser',
35
- data: err
36
- }
37
- });
38
- });
39
- };
40
- return {
41
- before: httpMultipartBodyParserMiddlewareBefore
42
- };
43
- };
44
- const parseMultipartData = (event, options)=>{
45
- const multipartData = {};
46
- const charset = event.isBase64Encoded ? 'base64' : options.charset;
47
- const busboy = BusBoy({
48
- ...options.busboy,
49
- headers: {
50
- 'content-type': event.headers?.['Content-Type'] ?? event.headers?.['content-type']
72
+
73
+ const chunks = []
74
+
75
+ file.on('data', (data) => {
76
+ chunks.push(data)
77
+ })
78
+ file.on('end', () => {
79
+ attachment.truncated = file.truncated
80
+ attachment.content = Buffer.concat(chunks)
81
+ if (!multipartData[fieldname]) {
82
+ multipartData[fieldname] = attachment
83
+ } else {
84
+ const current = multipartData[fieldname]
85
+ multipartData[fieldname] = [attachment].concat(current)
86
+ }
87
+ })
88
+ })
89
+ .on('field', (fieldname, value) => {
90
+ const matches = fieldname.match(fieldnamePattern)
91
+ if (!matches) {
92
+ multipartData[fieldname] = value
93
+ } else {
94
+ if (!multipartData[matches[1]]) {
95
+ multipartData[matches[1]] = []
96
+ }
97
+ multipartData[matches[1]].push(value)
51
98
  }
52
- });
53
- return new Promise((resolve, reject)=>{
54
- busboy.on('file', (fieldname, file, info)=>{
55
- const { filename, encoding, mimeType: mimetype } = info;
56
- const attachment = {
57
- filename,
58
- mimetype,
59
- encoding
60
- };
61
- const chunks = [];
62
- file.on('data', (data)=>{
63
- chunks.push(data);
64
- });
65
- file.on('end', ()=>{
66
- attachment.truncated = file.truncated;
67
- attachment.content = Buffer.concat(chunks);
68
- if (!multipartData[fieldname]) {
69
- multipartData[fieldname] = attachment;
70
- } else {
71
- const current = multipartData[fieldname];
72
- multipartData[fieldname] = [
73
- attachment
74
- ].concat(current);
75
- }
76
- });
77
- }).on('field', (fieldname, value)=>{
78
- const matches = fieldname.match(fieldnamePattern);
79
- if (!matches) {
80
- multipartData[fieldname] = value;
81
- } else {
82
- if (!multipartData[matches[1]]) {
83
- multipartData[matches[1]] = [];
84
- }
85
- multipartData[matches[1]].push(value);
86
- }
87
- }).on('finish', ()=>resolve(multipartData)).on('error', (e)=>reject(e));
88
- busboy.write(event.body, charset);
89
- busboy.end();
90
- });
91
- };
92
- export default httpMultipartBodyParserMiddleware;
99
+ })
100
+ .on('finish', () => resolve(multipartData))
101
+ .on('error', (e) => reject(e))
93
102
 
103
+ busboy.write(event.body, charset)
104
+ busboy.end()
105
+ })
106
+ }
107
+ export default httpMultipartBodyParserMiddleware
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@middy/http-multipart-body-parser",
3
- "version": "5.1.0",
3
+ "version": "5.2.1",
4
4
  "description": "Http event normalizer middleware for the middy framework",
5
5
  "type": "module",
6
6
  "engines": {
@@ -61,12 +61,12 @@
61
61
  },
62
62
  "dependencies": {
63
63
  "@fastify/busboy": "2.1.0",
64
- "@middy/util": "5.1.0"
64
+ "@middy/util": "5.2.1"
65
65
  },
66
66
  "devDependencies": {
67
- "@middy/core": "5.1.0",
67
+ "@middy/core": "5.2.1",
68
68
  "@types/aws-lambda": "^8.10.101",
69
69
  "type-fest": "^4.0.0"
70
70
  },
71
- "gitHead": "bbdaf5843914921804ba085dd58117273febe6b5"
71
+ "gitHead": "4d55da221b9165b4b3e59a12632fd40a149a1e92"
72
72
  }