multer-orm 2.0.1 → 2.0.2

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.
@@ -1,194 +1,194 @@
1
- var is = require('type-is')
2
- var Busboy = require('busboy')
3
- var extend = require('xtend')
4
- var appendField = require('append-field')
5
-
6
- var Counter = require('./counter')
7
- var MulterError = require('./multer-error')
8
- var FileAppender = require('./file-appender')
9
- var removeUploadedFiles = require('./remove-uploaded-files')
10
-
11
- function drainStream (stream) {
12
- stream.on('readable', () => {
13
- while (stream.read() !== null) {}
14
- })
15
- }
16
-
17
- function makeMiddleware (setup) {
18
- return function multerMiddleware (req, res, next) {
19
- if (!is(req, ['multipart'])) return next()
20
-
21
- var options = setup()
22
-
23
- var limits = options.limits
24
- var storage = options.storage
25
- var fileFilter = options.fileFilter
26
- var fileStrategy = options.fileStrategy
27
- var preservePath = options.preservePath
28
-
29
- req.body = Object.create(null)
30
-
31
- req.on('error', function (err) {
32
- abortWithError(err)
33
- })
34
-
35
- var busboy
36
-
37
- try {
38
- busboy = Busboy({ headers: req.headers, limits: limits, preservePath: preservePath })
39
- } catch (err) {
40
- return next(err)
41
- }
42
-
43
- var appender = new FileAppender(fileStrategy, req)
44
- var isDone = false
45
- var readFinished = false
46
- var errorOccured = false
47
- var pendingWrites = new Counter()
48
- var uploadedFiles = []
49
-
50
- function done (err) {
51
- if (isDone) return
52
- isDone = true
53
- req.unpipe(busboy)
54
- drainStream(req)
55
- req.resume()
56
- setImmediate(() => {
57
- busboy.removeAllListeners()
58
- })
59
- next(err)
60
- }
61
-
62
- function indicateDone () {
63
- if (readFinished && pendingWrites.isZero() && !errorOccured) done()
64
- }
65
-
66
- function abortWithError (uploadError) {
67
- if (errorOccured) return
68
- errorOccured = true
69
-
70
- pendingWrites.onceZero(function () {
71
- function remove (file, cb) {
72
- storage._removeFile(req, file, cb)
73
- }
74
-
75
- removeUploadedFiles(uploadedFiles, remove, function (err, storageErrors) {
76
- if (err) return done(err)
77
-
78
- uploadError.storageErrors = storageErrors
79
- done(uploadError)
80
- })
81
- })
82
- }
83
-
84
- function abortWithCode (code, optionalField) {
85
- abortWithError(new MulterError(code, optionalField))
86
- }
87
-
88
- // handle text field data
89
- busboy.on('field', function (fieldname, value, { nameTruncated, valueTruncated }) {
90
- if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
91
- if (nameTruncated) return abortWithCode('LIMIT_FIELD_KEY')
92
- if (valueTruncated) return abortWithCode('LIMIT_FIELD_VALUE', fieldname)
93
-
94
- // Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
95
- if (limits && Object.prototype.hasOwnProperty.call(limits, 'fieldNameSize')) {
96
- if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
97
- }
98
-
99
- appendField(req.body, fieldname, value)
100
- })
101
-
102
- // handle files
103
- busboy.on('file', function (fieldname, fileStream, { filename, encoding, mimeType }) {
104
- var pendingWritesIncremented = false
105
-
106
- fileStream.on('error', function (err) {
107
- if (pendingWritesIncremented) {
108
- pendingWrites.decrement()
109
- }
110
- abortWithError(err)
111
- })
112
-
113
- if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
114
-
115
- // don't attach to the files object, if there is no file
116
- if (!filename) return fileStream.resume()
117
-
118
- // Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
119
- if (limits && Object.prototype.hasOwnProperty.call(limits, 'fieldNameSize')) {
120
- if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
121
- }
122
-
123
- var file = {
124
- fieldname: fieldname,
125
- originalname: filename,
126
- encoding: encoding,
127
- mimetype: mimeType
128
- }
129
-
130
- var placeholder = appender.insertPlaceholder(file)
131
-
132
- fileFilter(req, file, function (err, includeFile) {
133
- if (err) {
134
- appender.removePlaceholder(placeholder)
135
- return abortWithError(err)
136
- }
137
-
138
- if (!includeFile) {
139
- appender.removePlaceholder(placeholder)
140
- return fileStream.resume()
141
- }
142
-
143
- var aborting = false
144
- pendingWritesIncremented = true
145
- pendingWrites.increment()
146
-
147
- Object.defineProperty(file, 'stream', {
148
- configurable: true,
149
- enumerable: false,
150
- value: fileStream
151
- })
152
-
153
- fileStream.on('limit', function () {
154
- aborting = true
155
- abortWithCode('LIMIT_FILE_SIZE', fieldname)
156
- })
157
-
158
- storage._handleFile(req, file, function (err, info) {
159
- if (aborting) {
160
- appender.removePlaceholder(placeholder)
161
- uploadedFiles.push(extend(file, info))
162
- return pendingWrites.decrement()
163
- }
164
-
165
- if (err) {
166
- appender.removePlaceholder(placeholder)
167
- pendingWrites.decrement()
168
- return abortWithError(err)
169
- }
170
-
171
- var fileInfo = extend(file, info)
172
-
173
- appender.replacePlaceholder(placeholder, fileInfo)
174
- uploadedFiles.push(fileInfo)
175
- pendingWrites.decrement()
176
- indicateDone()
177
- })
178
- })
179
- })
180
-
181
- busboy.on('error', function (err) { abortWithError(err) })
182
- busboy.on('partsLimit', function () { abortWithCode('LIMIT_PART_COUNT') })
183
- busboy.on('filesLimit', function () { abortWithCode('LIMIT_FILE_COUNT') })
184
- busboy.on('fieldsLimit', function () { abortWithCode('LIMIT_FIELD_COUNT') })
185
- busboy.on('close', function () {
186
- readFinished = true
187
- indicateDone()
188
- })
189
-
190
- req.pipe(busboy)
191
- }
192
- }
193
-
194
- module.exports = makeMiddleware
1
+ var is = require('type-is')
2
+ var Busboy = require('busboy')
3
+ var extend = require('xtend')
4
+ var appendField = require('append-field')
5
+
6
+ var Counter = require('./counter')
7
+ var MulterError = require('./multer-error')
8
+ var FileAppender = require('./file-appender')
9
+ var removeUploadedFiles = require('./remove-uploaded-files')
10
+
11
+ function drainStream (stream) {
12
+ stream.on('readable', () => {
13
+ while (stream.read() !== null) {}
14
+ })
15
+ }
16
+
17
+ function makeMiddleware (setup) {
18
+ return function multerMiddleware (req, res, next) {
19
+ if (!is(req, ['multipart'])) return next()
20
+
21
+ var options = setup()
22
+
23
+ var limits = options.limits
24
+ var storage = options.storage
25
+ var fileFilter = options.fileFilter
26
+ var fileStrategy = options.fileStrategy
27
+ var preservePath = options.preservePath
28
+
29
+ req.body = Object.create(null)
30
+
31
+ req.on('error', function (err) {
32
+ abortWithError(err)
33
+ })
34
+
35
+ var busboy
36
+
37
+ try {
38
+ busboy = Busboy({ headers: req.headers, limits: limits, preservePath: preservePath })
39
+ } catch (err) {
40
+ return next(err)
41
+ }
42
+
43
+ var appender = new FileAppender(fileStrategy, req)
44
+ var isDone = false
45
+ var readFinished = false
46
+ var errorOccured = false
47
+ var pendingWrites = new Counter()
48
+ var uploadedFiles = []
49
+
50
+ function done (err) {
51
+ if (isDone) return
52
+ isDone = true
53
+ req.unpipe(busboy)
54
+ drainStream(req)
55
+ req.resume()
56
+ setImmediate(() => {
57
+ busboy.removeAllListeners()
58
+ })
59
+ next(err)
60
+ }
61
+
62
+ function indicateDone () {
63
+ if (readFinished && pendingWrites.isZero() && !errorOccured) done()
64
+ }
65
+
66
+ function abortWithError (uploadError) {
67
+ if (errorOccured) return
68
+ errorOccured = true
69
+
70
+ pendingWrites.onceZero(function () {
71
+ function remove (file, cb) {
72
+ storage._removeFile(req, file, cb)
73
+ }
74
+
75
+ removeUploadedFiles(uploadedFiles, remove, function (err, storageErrors) {
76
+ if (err) return done(err)
77
+
78
+ uploadError.storageErrors = storageErrors
79
+ done(uploadError)
80
+ })
81
+ })
82
+ }
83
+
84
+ function abortWithCode (code, optionalField) {
85
+ abortWithError(new MulterError(code, optionalField))
86
+ }
87
+
88
+ // handle text field data
89
+ busboy.on('field', function (fieldname, value, { nameTruncated, valueTruncated }) {
90
+ if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
91
+ if (nameTruncated) return abortWithCode('LIMIT_FIELD_KEY')
92
+ if (valueTruncated) return abortWithCode('LIMIT_FIELD_VALUE', fieldname)
93
+
94
+ // Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
95
+ if (limits && Object.prototype.hasOwnProperty.call(limits, 'fieldNameSize')) {
96
+ if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
97
+ }
98
+
99
+ appendField(req.body, fieldname, value)
100
+ })
101
+
102
+ // handle files
103
+ busboy.on('file', function (fieldname, fileStream, { filename, encoding, mimeType }) {
104
+ var pendingWritesIncremented = false
105
+
106
+ fileStream.on('error', function (err) {
107
+ if (pendingWritesIncremented) {
108
+ pendingWrites.decrement()
109
+ }
110
+ abortWithError(err)
111
+ })
112
+
113
+ if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
114
+
115
+ // don't attach to the files object, if there is no file
116
+ if (!filename) return fileStream.resume()
117
+
118
+ // Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
119
+ if (limits && Object.prototype.hasOwnProperty.call(limits, 'fieldNameSize')) {
120
+ if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
121
+ }
122
+
123
+ var file = {
124
+ fieldname: fieldname,
125
+ originalname: filename,
126
+ encoding: encoding,
127
+ mimetype: mimeType
128
+ }
129
+
130
+ var placeholder = appender.insertPlaceholder(file)
131
+
132
+ fileFilter(req, file, function (err, includeFile) {
133
+ if (err) {
134
+ appender.removePlaceholder(placeholder)
135
+ return abortWithError(err)
136
+ }
137
+
138
+ if (!includeFile) {
139
+ appender.removePlaceholder(placeholder)
140
+ return fileStream.resume()
141
+ }
142
+
143
+ var aborting = false
144
+ pendingWritesIncremented = true
145
+ pendingWrites.increment()
146
+
147
+ Object.defineProperty(file, 'stream', {
148
+ configurable: true,
149
+ enumerable: false,
150
+ value: fileStream
151
+ })
152
+
153
+ fileStream.on('limit', function () {
154
+ aborting = true
155
+ abortWithCode('LIMIT_FILE_SIZE', fieldname)
156
+ })
157
+
158
+ storage._handleFile(req, file, function (err, info) {
159
+ if (aborting) {
160
+ appender.removePlaceholder(placeholder)
161
+ uploadedFiles.push(extend(file, info))
162
+ return pendingWrites.decrement()
163
+ }
164
+
165
+ if (err) {
166
+ appender.removePlaceholder(placeholder)
167
+ pendingWrites.decrement()
168
+ return abortWithError(err)
169
+ }
170
+
171
+ var fileInfo = extend(file, info)
172
+
173
+ appender.replacePlaceholder(placeholder, fileInfo)
174
+ uploadedFiles.push(fileInfo)
175
+ pendingWrites.decrement()
176
+ indicateDone()
177
+ })
178
+ })
179
+ })
180
+
181
+ busboy.on('error', function (err) { abortWithError(err) })
182
+ busboy.on('partsLimit', function () { abortWithCode('LIMIT_PART_COUNT') })
183
+ busboy.on('filesLimit', function () { abortWithCode('LIMIT_FILE_COUNT') })
184
+ busboy.on('fieldsLimit', function () { abortWithCode('LIMIT_FIELD_COUNT') })
185
+ busboy.on('close', function () {
186
+ readFinished = true
187
+ indicateDone()
188
+ })
189
+
190
+ req.pipe(busboy)
191
+ }
192
+ }
193
+
194
+ module.exports = makeMiddleware
@@ -1,24 +1,24 @@
1
- var util = require('util')
2
-
3
- var errorMessages = {
4
- LIMIT_PART_COUNT: 'Too many parts',
5
- LIMIT_FILE_SIZE: 'File too large',
6
- LIMIT_FILE_COUNT: 'Too many files',
7
- LIMIT_FIELD_KEY: 'Field name too long',
8
- LIMIT_FIELD_VALUE: 'Field value too long',
9
- LIMIT_FIELD_COUNT: 'Too many fields',
10
- LIMIT_UNEXPECTED_FILE: 'Unexpected field',
11
- MISSING_FIELD_NAME: 'Field name missing'
12
- }
13
-
14
- function MulterError (code, field) {
15
- Error.captureStackTrace(this, this.constructor)
16
- this.name = this.constructor.name
17
- this.message = errorMessages[code]
18
- this.code = code
19
- if (field) this.field = field
20
- }
21
-
22
- util.inherits(MulterError, Error)
23
-
24
- module.exports = MulterError
1
+ var util = require('util')
2
+
3
+ var errorMessages = {
4
+ LIMIT_PART_COUNT: 'Too many parts',
5
+ LIMIT_FILE_SIZE: 'File too large',
6
+ LIMIT_FILE_COUNT: 'Too many files',
7
+ LIMIT_FIELD_KEY: 'Field name too long',
8
+ LIMIT_FIELD_VALUE: 'Field value too long',
9
+ LIMIT_FIELD_COUNT: 'Too many fields',
10
+ LIMIT_UNEXPECTED_FILE: 'Unexpected field',
11
+ MISSING_FIELD_NAME: 'Field name missing'
12
+ }
13
+
14
+ function MulterError (code, field) {
15
+ Error.captureStackTrace(this, this.constructor)
16
+ this.name = this.constructor.name
17
+ this.message = errorMessages[code]
18
+ this.code = code
19
+ if (field) this.field = field
20
+ }
21
+
22
+ util.inherits(MulterError, Error)
23
+
24
+ module.exports = MulterError
@@ -1,28 +1,28 @@
1
- function removeUploadedFiles (uploadedFiles, remove, cb) {
2
- var length = uploadedFiles.length
3
- var errors = []
4
-
5
- if (length === 0) return cb(null, errors)
6
-
7
- function handleFile (idx) {
8
- var file = uploadedFiles[idx]
9
-
10
- remove(file, function (err) {
11
- if (err) {
12
- err.file = file
13
- err.field = file.fieldname
14
- errors.push(err)
15
- }
16
-
17
- if (idx < length - 1) {
18
- handleFile(idx + 1)
19
- } else {
20
- cb(null, errors)
21
- }
22
- })
23
- }
24
-
25
- handleFile(0)
26
- }
27
-
28
- module.exports = removeUploadedFiles
1
+ function removeUploadedFiles (uploadedFiles, remove, cb) {
2
+ var length = uploadedFiles.length
3
+ var errors = []
4
+
5
+ if (length === 0) return cb(null, errors)
6
+
7
+ function handleFile (idx) {
8
+ var file = uploadedFiles[idx]
9
+
10
+ remove(file, function (err) {
11
+ if (err) {
12
+ err.file = file
13
+ err.field = file.fieldname
14
+ errors.push(err)
15
+ }
16
+
17
+ if (idx < length - 1) {
18
+ handleFile(idx + 1)
19
+ } else {
20
+ cb(null, errors)
21
+ }
22
+ })
23
+ }
24
+
25
+ handleFile(0)
26
+ }
27
+
28
+ module.exports = removeUploadedFiles
package/package.json CHANGED
@@ -1,52 +1,57 @@
1
- {
2
- "name": "multer-orm",
3
- "description": "Multer ORM for handling `multipart/form-data`.",
4
- "version": "2.0.1",
5
- "license": "MIT",
6
- "repository": "expressjs/multer",
7
- "keywords": [
8
- "form",
9
- "post",
10
- "multipart",
11
- "form-data",
12
- "formdata",
13
- "express",
14
- "middleware"
15
- ],
16
- "dependencies": {
17
- "append-field": "^1.0.0",
18
- "busboy": "^1.6.0",
19
- "concat-stream": "^2.0.0",
20
- "mkdirp": "^0.5.6",
21
- "object-assign": "^4.1.1",
22
- "type-is": "^1.6.18",
23
- "xtend": "^4.0.2"
24
- },
25
- "devDependencies": {
26
- "deep-equal": "^2.0.3",
27
- "express": "^4.21.2",
28
- "form-data": "^4.0.2",
29
- "fs-temp": "^1.2.1",
30
- "mocha": "^11.5.0",
31
- "nyc": "^15.1.0",
32
- "rimraf": "^2.4.1",
33
- "standard": "^14.3.3",
34
- "testdata-w3c-json-form": "^1.0.0"
35
- },
36
- "engines": {
37
- "node": ">= 10.16.0"
38
- },
39
- "files": [
40
- "LICENSE",
41
- "index.js",
42
- "storage/",
43
- "lib/"
44
- ],
45
- "scripts": {
46
- "lint": "standard",
47
- "lint:fix": "standard --fix",
48
- "test": "mocha --reporter spec --exit --check-leaks test/",
49
- "test-ci": "nyc --reporter=lcov --reporter=text npm test",
50
- "test-cov": "nyc --reporter=html --reporter=text npm test"
51
- }
52
- }
1
+ {
2
+ "name": "multer-orm",
3
+ "description": "Middleware for handling `multipart/form-data`.",
4
+ "version": "2.0.2",
5
+ "contributors": [
6
+ "Hage Yaapa <captain@hacksparrow.com> (http://www.hacksparrow.com)",
7
+ "Jaret Pfluger <https://github.com/jpfluger>",
8
+ "Linus Unnebäck <linus@folkdatorn.se>"
9
+ ],
10
+ "license": "MIT",
11
+ "repository": "expressjs/multer",
12
+ "keywords": [
13
+ "form",
14
+ "post",
15
+ "multipart",
16
+ "form-data",
17
+ "formdata",
18
+ "express",
19
+ "middleware"
20
+ ],
21
+ "dependencies": {
22
+ "append-field": "^1.0.0",
23
+ "busboy": "^1.6.0",
24
+ "concat-stream": "^2.0.0",
25
+ "mkdirp": "^0.5.6",
26
+ "object-assign": "^4.1.1",
27
+ "type-is": "^1.6.18",
28
+ "xtend": "^4.0.2"
29
+ },
30
+ "devDependencies": {
31
+ "deep-equal": "^2.0.3",
32
+ "express": "^4.21.2",
33
+ "form-data": "^4.0.2",
34
+ "fs-temp": "^1.2.1",
35
+ "mocha": "^11.5.0",
36
+ "nyc": "^15.1.0",
37
+ "rimraf": "^2.4.1",
38
+ "standard": "^14.3.3",
39
+ "testdata-w3c-json-form": "^1.0.0"
40
+ },
41
+ "engines": {
42
+ "node": ">= 10.16.0"
43
+ },
44
+ "files": [
45
+ "LICENSE",
46
+ "index.js",
47
+ "storage/",
48
+ "lib/"
49
+ ],
50
+ "scripts": {
51
+ "lint": "standard",
52
+ "lint:fix": "standard --fix",
53
+ "test": "mocha --reporter spec --exit --check-leaks test/",
54
+ "test-ci": "nyc --reporter=lcov --reporter=text npm test",
55
+ "test-cov": "nyc --reporter=html --reporter=text npm test"
56
+ }
57
+ }