done purchases remove, ocr scan, read image
This commit is contained in:
62
express-server/node_modules/multer/CHANGELOG.md
generated
vendored
Normal file
62
express-server/node_modules/multer/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
# Change log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 1.4.1 - 2018-10-11
|
||||
|
||||
- Bugfix: Make sure that req.file.buffer always is a Buffer
|
||||
|
||||
## 1.4.0 - 2018-09-26
|
||||
|
||||
- Feature: Make Multer errors inherit from MulterError
|
||||
|
||||
## 1.3.1 - 2018-06-28
|
||||
|
||||
- Bugfix: Bump vulnerable dependency
|
||||
|
||||
## 1.3.0 - 2017-01-25
|
||||
|
||||
- Feature: Expose preservePath option
|
||||
|
||||
## 1.2.1 - 2016-12-14
|
||||
|
||||
- Bugfix: Prevent Multiple Errors from Crashing
|
||||
|
||||
## 1.2.0 - 2016-08-04
|
||||
|
||||
- Feature: add .none() for accepting only fields
|
||||
|
||||
## 1.1.0 - 2015-10-23
|
||||
|
||||
- Feature: accept any file, regardless of fieldname
|
||||
|
||||
## 1.0.6 - 2015-10-03
|
||||
|
||||
- Bugfix: always report limit errors
|
||||
|
||||
## 1.0.5 - 2015-09-19
|
||||
|
||||
- Bugfix: drain the stream before considering request done
|
||||
|
||||
## 1.0.4 - 2015-09-19
|
||||
|
||||
- Bugfix: propagate all errors from busboy
|
||||
|
||||
## 1.0.3 - 2015-08-06
|
||||
|
||||
- Bugfix: ensure file order is correct
|
||||
|
||||
## 1.0.2 - 2015-08-06
|
||||
|
||||
- Bugfix: don't hang when hitting size limit
|
||||
|
||||
## 1.0.1 - 2015-07-20
|
||||
|
||||
- Bugfix: decrement pending writes on error
|
||||
|
||||
## 1.0.0 - 2015-07-18
|
||||
|
||||
- Introduce storage engines
|
||||
- Specify expected fields
|
||||
- Follow the W3C JSON form spec
|
17
express-server/node_modules/multer/LICENSE
generated
vendored
Normal file
17
express-server/node_modules/multer/LICENSE
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
Copyright (c) 2014 Hage Yaapa <[http://www.hacksparrow.com](http://www.hacksparrow.com)>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
298
express-server/node_modules/multer/README.md
generated
vendored
Normal file
298
express-server/node_modules/multer/README.md
generated
vendored
Normal file
@ -0,0 +1,298 @@
|
||||
# Multer [](https://travis-ci.org/expressjs/multer) [](https://badge.fury.io/js/multer) [](https://github.com/feross/standard)
|
||||
|
||||
Multer is a node.js middleware for handling `multipart/form-data`, which is primarily used for uploading files. It is written
|
||||
on top of [busboy](https://github.com/mscdex/busboy) for maximum efficiency.
|
||||
|
||||
**NOTE**: Multer will not process any form which is not multipart (`multipart/form-data`).
|
||||
|
||||
## Translations
|
||||
|
||||
This README is also available in other languages:
|
||||
|
||||
- [简体中文](https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md) (Chinese)
|
||||
- [한국어](https://github.com/expressjs/multer/blob/master/doc/README-ko.md) (Korean)
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install --save multer
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Multer adds a `body` object and a `file` or `files` object to the `request` object. The `body` object contains the values of the text fields of the form, the `file` or `files` object contains the files uploaded via the form.
|
||||
|
||||
Basic usage example:
|
||||
|
||||
Don't forget the `enctype="multipart/form-data"` in your form.
|
||||
|
||||
```html
|
||||
<form action="/profile" method="post" enctype="multipart/form-data">
|
||||
<input type="file" name="avatar" />
|
||||
</form>
|
||||
```
|
||||
|
||||
```javascript
|
||||
var express = require('express')
|
||||
var multer = require('multer')
|
||||
var upload = multer({ dest: 'uploads/' })
|
||||
|
||||
var app = express()
|
||||
|
||||
app.post('/profile', upload.single('avatar'), function (req, res, next) {
|
||||
// req.file is the `avatar` file
|
||||
// req.body will hold the text fields, if there were any
|
||||
})
|
||||
|
||||
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
|
||||
// req.files is array of `photos` files
|
||||
// req.body will contain the text fields, if there were any
|
||||
})
|
||||
|
||||
var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
|
||||
app.post('/cool-profile', cpUpload, function (req, res, next) {
|
||||
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
|
||||
//
|
||||
// e.g.
|
||||
// req.files['avatar'][0] -> File
|
||||
// req.files['gallery'] -> Array
|
||||
//
|
||||
// req.body will contain the text fields, if there were any
|
||||
})
|
||||
```
|
||||
|
||||
In case you need to handle a text-only multipart form, you should use the `.none()` method:
|
||||
|
||||
```javascript
|
||||
var express = require('express')
|
||||
var app = express()
|
||||
var multer = require('multer')
|
||||
var upload = multer()
|
||||
|
||||
app.post('/profile', upload.none(), function (req, res, next) {
|
||||
// req.body contains the text fields
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### File information
|
||||
|
||||
Each file contains the following information:
|
||||
|
||||
Key | Description | Note
|
||||
--- | --- | ---
|
||||
`fieldname` | Field name specified in the form |
|
||||
`originalname` | Name of the file on the user's computer |
|
||||
`encoding` | Encoding type of the file |
|
||||
`mimetype` | Mime type of the file |
|
||||
`size` | Size of the file in bytes |
|
||||
`destination` | The folder to which the file has been saved | `DiskStorage`
|
||||
`filename` | The name of the file within the `destination` | `DiskStorage`
|
||||
`path` | The full path to the uploaded file | `DiskStorage`
|
||||
`buffer` | A `Buffer` of the entire file | `MemoryStorage`
|
||||
|
||||
### `multer(opts)`
|
||||
|
||||
Multer accepts an options object, the most basic of which is the `dest`
|
||||
property, which tells Multer where to upload the files. In case you omit the
|
||||
options object, the files will be kept in memory and never written to disk.
|
||||
|
||||
By default, Multer will rename the files so as to avoid naming conflicts. The
|
||||
renaming function can be customized according to your needs.
|
||||
|
||||
The following are the options that can be passed to Multer.
|
||||
|
||||
Key | Description
|
||||
--- | ---
|
||||
`dest` or `storage` | Where to store the files
|
||||
`fileFilter` | Function to control which files are accepted
|
||||
`limits` | Limits of the uploaded data
|
||||
`preservePath` | Keep the full path of files instead of just the base name
|
||||
|
||||
In an average web app, only `dest` might be required, and configured as shown in
|
||||
the following example.
|
||||
|
||||
```javascript
|
||||
var upload = multer({ dest: 'uploads/' })
|
||||
```
|
||||
|
||||
If you want more control over your uploads, you'll want to use the `storage`
|
||||
option instead of `dest`. Multer ships with storage engines `DiskStorage`
|
||||
and `MemoryStorage`; More engines are available from third parties.
|
||||
|
||||
#### `.single(fieldname)`
|
||||
|
||||
Accept a single file with the name `fieldname`. The single file will be stored
|
||||
in `req.file`.
|
||||
|
||||
#### `.array(fieldname[, maxCount])`
|
||||
|
||||
Accept an array of files, all with the name `fieldname`. Optionally error out if
|
||||
more than `maxCount` files are uploaded. The array of files will be stored in
|
||||
`req.files`.
|
||||
|
||||
#### `.fields(fields)`
|
||||
|
||||
Accept a mix of files, specified by `fields`. An object with arrays of files
|
||||
will be stored in `req.files`.
|
||||
|
||||
`fields` should be an array of objects with `name` and optionally a `maxCount`.
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
[
|
||||
{ name: 'avatar', maxCount: 1 },
|
||||
{ name: 'gallery', maxCount: 8 }
|
||||
]
|
||||
```
|
||||
|
||||
#### `.none()`
|
||||
|
||||
Accept only text fields. If any file upload is made, error with code
|
||||
"LIMIT\_UNEXPECTED\_FILE" will be issued.
|
||||
|
||||
#### `.any()`
|
||||
|
||||
Accepts all files that comes over the wire. An array of files will be stored in
|
||||
`req.files`.
|
||||
|
||||
**WARNING:** Make sure that you always handle the files that a user uploads.
|
||||
Never add multer as a global middleware since a malicious user could upload
|
||||
files to a route that you didn't anticipate. Only use this function on routes
|
||||
where you are handling the uploaded files.
|
||||
|
||||
### `storage`
|
||||
|
||||
#### `DiskStorage`
|
||||
|
||||
The disk storage engine gives you full control on storing files to disk.
|
||||
|
||||
```javascript
|
||||
var storage = multer.diskStorage({
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, '/tmp/my-uploads')
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
cb(null, file.fieldname + '-' + Date.now())
|
||||
}
|
||||
})
|
||||
|
||||
var upload = multer({ storage: storage })
|
||||
```
|
||||
|
||||
There are two options available, `destination` and `filename`. They are both
|
||||
functions that determine where the file should be stored.
|
||||
|
||||
`destination` is used to determine within which folder the uploaded files should
|
||||
be stored. This can also be given as a `string` (e.g. `'/tmp/uploads'`). If no
|
||||
`destination` is given, the operating system's default directory for temporary
|
||||
files is used.
|
||||
|
||||
**Note:** You are responsible for creating the directory when providing
|
||||
`destination` as a function. When passing a string, multer will make sure that
|
||||
the directory is created for you.
|
||||
|
||||
`filename` is used to determine what the file should be named inside the folder.
|
||||
If no `filename` is given, each file will be given a random name that doesn't
|
||||
include any file extension.
|
||||
|
||||
**Note:** Multer will not append any file extension for you, your function
|
||||
should return a filename complete with an file extension.
|
||||
|
||||
Each function gets passed both the request (`req`) and some information about
|
||||
the file (`file`) to aid with the decision.
|
||||
|
||||
Note that `req.body` might not have been fully populated yet. It depends on the
|
||||
order that the client transmits fields and files to the server.
|
||||
|
||||
#### `MemoryStorage`
|
||||
|
||||
The memory storage engine stores the files in memory as `Buffer` objects. It
|
||||
doesn't have any options.
|
||||
|
||||
```javascript
|
||||
var storage = multer.memoryStorage()
|
||||
var upload = multer({ storage: storage })
|
||||
```
|
||||
|
||||
When using memory storage, the file info will contain a field called
|
||||
`buffer` that contains the entire file.
|
||||
|
||||
**WARNING**: Uploading very large files, or relatively small files in large
|
||||
numbers very quickly, can cause your application to run out of memory when
|
||||
memory storage is used.
|
||||
|
||||
### `limits`
|
||||
|
||||
An object specifying the size limits of the following optional properties. Multer passes this object into busboy directly, and the details of the properties can be found on [busboy's page](https://github.com/mscdex/busboy#busboy-methods).
|
||||
|
||||
The following integer values are available:
|
||||
|
||||
Key | Description | Default
|
||||
--- | --- | ---
|
||||
`fieldNameSize` | Max field name size | 100 bytes
|
||||
`fieldSize` | Max field value size | 1MB
|
||||
`fields` | Max number of non-file fields | Infinity
|
||||
`fileSize` | For multipart forms, the max file size (in bytes) | Infinity
|
||||
`files` | For multipart forms, the max number of file fields | Infinity
|
||||
`parts` | For multipart forms, the max number of parts (fields + files) | Infinity
|
||||
`headerPairs` | For multipart forms, the max number of header key=>value pairs to parse | 2000
|
||||
|
||||
Specifying the limits can help protect your site against denial of service (DoS) attacks.
|
||||
|
||||
### `fileFilter`
|
||||
|
||||
Set this to a function to control which files should be uploaded and which
|
||||
should be skipped. The function should look like this:
|
||||
|
||||
```javascript
|
||||
function fileFilter (req, file, cb) {
|
||||
|
||||
// The function should call `cb` with a boolean
|
||||
// to indicate if the file should be accepted
|
||||
|
||||
// To reject this file pass `false`, like so:
|
||||
cb(null, false)
|
||||
|
||||
// To accept the file pass `true`, like so:
|
||||
cb(null, true)
|
||||
|
||||
// You can always pass an error if something goes wrong:
|
||||
cb(new Error('I don\'t have a clue!'))
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Error handling
|
||||
|
||||
When encountering an error, Multer will delegate the error to Express. You can
|
||||
display a nice error page using [the standard express way](http://expressjs.com/guide/error-handling.html).
|
||||
|
||||
If you want to catch errors specifically from Multer, you can call the
|
||||
middleware function by yourself. Also, if you want to catch only [the Multer errors](https://github.com/expressjs/multer/blob/master/lib/make-error.js#L1-L9), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
|
||||
|
||||
```javascript
|
||||
var multer = require('multer')
|
||||
var upload = multer().single('avatar')
|
||||
|
||||
app.post('/profile', function (req, res) {
|
||||
upload(req, res, function (err) {
|
||||
if (err instanceof multer.MulterError) {
|
||||
// A Multer error occurred when uploading.
|
||||
} else if (err) {
|
||||
// An unknown error occurred when uploading.
|
||||
}
|
||||
|
||||
// Everything went fine.
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Custom storage engine
|
||||
|
||||
For information on how to build your own storage engine, see [Multer Storage Engine](https://github.com/expressjs/multer/blob/master/StorageEngine.md).
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
104
express-server/node_modules/multer/index.js
generated
vendored
Normal file
104
express-server/node_modules/multer/index.js
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
var makeMiddleware = require('./lib/make-middleware')
|
||||
|
||||
var diskStorage = require('./storage/disk')
|
||||
var memoryStorage = require('./storage/memory')
|
||||
var MulterError = require('./lib/multer-error')
|
||||
|
||||
function allowAll (req, file, cb) {
|
||||
cb(null, true)
|
||||
}
|
||||
|
||||
function Multer (options) {
|
||||
if (options.storage) {
|
||||
this.storage = options.storage
|
||||
} else if (options.dest) {
|
||||
this.storage = diskStorage({ destination: options.dest })
|
||||
} else {
|
||||
this.storage = memoryStorage()
|
||||
}
|
||||
|
||||
this.limits = options.limits
|
||||
this.preservePath = options.preservePath
|
||||
this.fileFilter = options.fileFilter || allowAll
|
||||
}
|
||||
|
||||
Multer.prototype._makeMiddleware = function (fields, fileStrategy) {
|
||||
function setup () {
|
||||
var fileFilter = this.fileFilter
|
||||
var filesLeft = Object.create(null)
|
||||
|
||||
fields.forEach(function (field) {
|
||||
if (typeof field.maxCount === 'number') {
|
||||
filesLeft[field.name] = field.maxCount
|
||||
} else {
|
||||
filesLeft[field.name] = Infinity
|
||||
}
|
||||
})
|
||||
|
||||
function wrappedFileFilter (req, file, cb) {
|
||||
if ((filesLeft[file.fieldname] || 0) <= 0) {
|
||||
return cb(new MulterError('LIMIT_UNEXPECTED_FILE', file.fieldname))
|
||||
}
|
||||
|
||||
filesLeft[file.fieldname] -= 1
|
||||
fileFilter(req, file, cb)
|
||||
}
|
||||
|
||||
return {
|
||||
limits: this.limits,
|
||||
preservePath: this.preservePath,
|
||||
storage: this.storage,
|
||||
fileFilter: wrappedFileFilter,
|
||||
fileStrategy: fileStrategy
|
||||
}
|
||||
}
|
||||
|
||||
return makeMiddleware(setup.bind(this))
|
||||
}
|
||||
|
||||
Multer.prototype.single = function (name) {
|
||||
return this._makeMiddleware([{ name: name, maxCount: 1 }], 'VALUE')
|
||||
}
|
||||
|
||||
Multer.prototype.array = function (name, maxCount) {
|
||||
return this._makeMiddleware([{ name: name, maxCount: maxCount }], 'ARRAY')
|
||||
}
|
||||
|
||||
Multer.prototype.fields = function (fields) {
|
||||
return this._makeMiddleware(fields, 'OBJECT')
|
||||
}
|
||||
|
||||
Multer.prototype.none = function () {
|
||||
return this._makeMiddleware([], 'NONE')
|
||||
}
|
||||
|
||||
Multer.prototype.any = function () {
|
||||
function setup () {
|
||||
return {
|
||||
limits: this.limits,
|
||||
preservePath: this.preservePath,
|
||||
storage: this.storage,
|
||||
fileFilter: this.fileFilter,
|
||||
fileStrategy: 'ARRAY'
|
||||
}
|
||||
}
|
||||
|
||||
return makeMiddleware(setup.bind(this))
|
||||
}
|
||||
|
||||
function multer (options) {
|
||||
if (options === undefined) {
|
||||
return new Multer({})
|
||||
}
|
||||
|
||||
if (typeof options === 'object' && options !== null) {
|
||||
return new Multer(options)
|
||||
}
|
||||
|
||||
throw new TypeError('Expected object for argument options')
|
||||
}
|
||||
|
||||
module.exports = multer
|
||||
module.exports.diskStorage = diskStorage
|
||||
module.exports.memoryStorage = memoryStorage
|
||||
module.exports.MulterError = MulterError
|
28
express-server/node_modules/multer/lib/counter.js
generated
vendored
Normal file
28
express-server/node_modules/multer/lib/counter.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
|
||||
function Counter () {
|
||||
EventEmitter.call(this)
|
||||
this.value = 0
|
||||
}
|
||||
|
||||
Counter.prototype = Object.create(EventEmitter.prototype)
|
||||
|
||||
Counter.prototype.increment = function increment () {
|
||||
this.value++
|
||||
}
|
||||
|
||||
Counter.prototype.decrement = function decrement () {
|
||||
if (--this.value === 0) this.emit('zero')
|
||||
}
|
||||
|
||||
Counter.prototype.isZero = function isZero () {
|
||||
return (this.value === 0)
|
||||
}
|
||||
|
||||
Counter.prototype.onceZero = function onceZero (fn) {
|
||||
if (this.isZero()) return fn()
|
||||
|
||||
this.once('zero', fn)
|
||||
}
|
||||
|
||||
module.exports = Counter
|
67
express-server/node_modules/multer/lib/file-appender.js
generated
vendored
Normal file
67
express-server/node_modules/multer/lib/file-appender.js
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
var objectAssign = require('object-assign')
|
||||
|
||||
function arrayRemove (arr, item) {
|
||||
var idx = arr.indexOf(item)
|
||||
if (~idx) arr.splice(idx, 1)
|
||||
}
|
||||
|
||||
function FileAppender (strategy, req) {
|
||||
this.strategy = strategy
|
||||
this.req = req
|
||||
|
||||
switch (strategy) {
|
||||
case 'NONE': break
|
||||
case 'VALUE': break
|
||||
case 'ARRAY': req.files = []; break
|
||||
case 'OBJECT': req.files = Object.create(null); break
|
||||
default: throw new Error('Unknown file strategy: ' + strategy)
|
||||
}
|
||||
}
|
||||
|
||||
FileAppender.prototype.insertPlaceholder = function (file) {
|
||||
var placeholder = {
|
||||
fieldname: file.fieldname
|
||||
}
|
||||
|
||||
switch (this.strategy) {
|
||||
case 'NONE': break
|
||||
case 'VALUE': break
|
||||
case 'ARRAY': this.req.files.push(placeholder); break
|
||||
case 'OBJECT':
|
||||
if (this.req.files[file.fieldname]) {
|
||||
this.req.files[file.fieldname].push(placeholder)
|
||||
} else {
|
||||
this.req.files[file.fieldname] = [placeholder]
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return placeholder
|
||||
}
|
||||
|
||||
FileAppender.prototype.removePlaceholder = function (placeholder) {
|
||||
switch (this.strategy) {
|
||||
case 'NONE': break
|
||||
case 'VALUE': break
|
||||
case 'ARRAY': arrayRemove(this.req.files, placeholder); break
|
||||
case 'OBJECT':
|
||||
if (this.req.files[placeholder.fieldname].length === 1) {
|
||||
delete this.req.files[placeholder.fieldname]
|
||||
} else {
|
||||
arrayRemove(this.req.files[placeholder.fieldname], placeholder)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
FileAppender.prototype.replacePlaceholder = function (placeholder, file) {
|
||||
if (this.strategy === 'VALUE') {
|
||||
this.req.file = file
|
||||
return
|
||||
}
|
||||
|
||||
delete placeholder.fieldname
|
||||
objectAssign(placeholder, file)
|
||||
}
|
||||
|
||||
module.exports = FileAppender
|
180
express-server/node_modules/multer/lib/make-middleware.js
generated
vendored
Normal file
180
express-server/node_modules/multer/lib/make-middleware.js
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
var is = require('type-is')
|
||||
var Busboy = require('busboy')
|
||||
var extend = require('xtend')
|
||||
var onFinished = require('on-finished')
|
||||
var appendField = require('append-field')
|
||||
|
||||
var Counter = require('./counter')
|
||||
var MulterError = require('./multer-error')
|
||||
var FileAppender = require('./file-appender')
|
||||
var removeUploadedFiles = require('./remove-uploaded-files')
|
||||
|
||||
function drainStream (stream) {
|
||||
stream.on('readable', stream.read.bind(stream))
|
||||
}
|
||||
|
||||
function makeMiddleware (setup) {
|
||||
return function multerMiddleware (req, res, next) {
|
||||
if (!is(req, ['multipart'])) return next()
|
||||
|
||||
var options = setup()
|
||||
|
||||
var limits = options.limits
|
||||
var storage = options.storage
|
||||
var fileFilter = options.fileFilter
|
||||
var fileStrategy = options.fileStrategy
|
||||
var preservePath = options.preservePath
|
||||
|
||||
req.body = Object.create(null)
|
||||
|
||||
var busboy
|
||||
|
||||
try {
|
||||
busboy = new Busboy({ headers: req.headers, limits: limits, preservePath: preservePath })
|
||||
} catch (err) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
var appender = new FileAppender(fileStrategy, req)
|
||||
var isDone = false
|
||||
var readFinished = false
|
||||
var errorOccured = false
|
||||
var pendingWrites = new Counter()
|
||||
var uploadedFiles = []
|
||||
|
||||
function done (err) {
|
||||
if (isDone) return
|
||||
isDone = true
|
||||
|
||||
req.unpipe(busboy)
|
||||
drainStream(req)
|
||||
busboy.removeAllListeners()
|
||||
|
||||
onFinished(req, function () { next(err) })
|
||||
}
|
||||
|
||||
function indicateDone () {
|
||||
if (readFinished && pendingWrites.isZero() && !errorOccured) done()
|
||||
}
|
||||
|
||||
function abortWithError (uploadError) {
|
||||
if (errorOccured) return
|
||||
errorOccured = true
|
||||
|
||||
pendingWrites.onceZero(function () {
|
||||
function remove (file, cb) {
|
||||
storage._removeFile(req, file, cb)
|
||||
}
|
||||
|
||||
removeUploadedFiles(uploadedFiles, remove, function (err, storageErrors) {
|
||||
if (err) return done(err)
|
||||
|
||||
uploadError.storageErrors = storageErrors
|
||||
done(uploadError)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function abortWithCode (code, optionalField) {
|
||||
abortWithError(new MulterError(code, optionalField))
|
||||
}
|
||||
|
||||
// handle text field data
|
||||
busboy.on('field', function (fieldname, value, fieldnameTruncated, valueTruncated) {
|
||||
if (fieldnameTruncated) return abortWithCode('LIMIT_FIELD_KEY')
|
||||
if (valueTruncated) return abortWithCode('LIMIT_FIELD_VALUE', fieldname)
|
||||
|
||||
// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
|
||||
if (limits && limits.hasOwnProperty('fieldNameSize')) {
|
||||
if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
|
||||
}
|
||||
|
||||
appendField(req.body, fieldname, value)
|
||||
})
|
||||
|
||||
// handle files
|
||||
busboy.on('file', function (fieldname, fileStream, filename, encoding, mimetype) {
|
||||
// don't attach to the files object, if there is no file
|
||||
if (!filename) return fileStream.resume()
|
||||
|
||||
// Work around bug in Busboy (https://github.com/mscdex/busboy/issues/6)
|
||||
if (limits && limits.hasOwnProperty('fieldNameSize')) {
|
||||
if (fieldname.length > limits.fieldNameSize) return abortWithCode('LIMIT_FIELD_KEY')
|
||||
}
|
||||
|
||||
var file = {
|
||||
fieldname: fieldname,
|
||||
originalname: filename,
|
||||
encoding: encoding,
|
||||
mimetype: mimetype
|
||||
}
|
||||
|
||||
var placeholder = appender.insertPlaceholder(file)
|
||||
|
||||
fileFilter(req, file, function (err, includeFile) {
|
||||
if (err) {
|
||||
appender.removePlaceholder(placeholder)
|
||||
return abortWithError(err)
|
||||
}
|
||||
|
||||
if (!includeFile) {
|
||||
appender.removePlaceholder(placeholder)
|
||||
return fileStream.resume()
|
||||
}
|
||||
|
||||
var aborting = false
|
||||
pendingWrites.increment()
|
||||
|
||||
Object.defineProperty(file, 'stream', {
|
||||
configurable: true,
|
||||
enumerable: false,
|
||||
value: fileStream
|
||||
})
|
||||
|
||||
fileStream.on('error', function (err) {
|
||||
pendingWrites.decrement()
|
||||
abortWithError(err)
|
||||
})
|
||||
|
||||
fileStream.on('limit', function () {
|
||||
aborting = true
|
||||
abortWithCode('LIMIT_FILE_SIZE', fieldname)
|
||||
})
|
||||
|
||||
storage._handleFile(req, file, function (err, info) {
|
||||
if (aborting) {
|
||||
appender.removePlaceholder(placeholder)
|
||||
uploadedFiles.push(extend(file, info))
|
||||
return pendingWrites.decrement()
|
||||
}
|
||||
|
||||
if (err) {
|
||||
appender.removePlaceholder(placeholder)
|
||||
pendingWrites.decrement()
|
||||
return abortWithError(err)
|
||||
}
|
||||
|
||||
var fileInfo = extend(file, info)
|
||||
|
||||
appender.replacePlaceholder(placeholder, fileInfo)
|
||||
uploadedFiles.push(fileInfo)
|
||||
pendingWrites.decrement()
|
||||
indicateDone()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
busboy.on('error', function (err) { abortWithError(err) })
|
||||
busboy.on('partsLimit', function () { abortWithCode('LIMIT_PART_COUNT') })
|
||||
busboy.on('filesLimit', function () { abortWithCode('LIMIT_FILE_COUNT') })
|
||||
busboy.on('fieldsLimit', function () { abortWithCode('LIMIT_FIELD_COUNT') })
|
||||
busboy.on('finish', function () {
|
||||
readFinished = true
|
||||
indicateDone()
|
||||
})
|
||||
|
||||
req.pipe(busboy)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = makeMiddleware
|
23
express-server/node_modules/multer/lib/multer-error.js
generated
vendored
Normal file
23
express-server/node_modules/multer/lib/multer-error.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
var util = require('util')
|
||||
|
||||
var errorMessages = {
|
||||
'LIMIT_PART_COUNT': 'Too many parts',
|
||||
'LIMIT_FILE_SIZE': 'File too large',
|
||||
'LIMIT_FILE_COUNT': 'Too many files',
|
||||
'LIMIT_FIELD_KEY': 'Field name too long',
|
||||
'LIMIT_FIELD_VALUE': 'Field value too long',
|
||||
'LIMIT_FIELD_COUNT': 'Too many fields',
|
||||
'LIMIT_UNEXPECTED_FILE': 'Unexpected field'
|
||||
}
|
||||
|
||||
function MulterError (code, field) {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
this.name = this.constructor.name
|
||||
this.message = errorMessages[code]
|
||||
this.code = code
|
||||
if (field) this.field = field
|
||||
}
|
||||
|
||||
util.inherits(MulterError, Error)
|
||||
|
||||
module.exports = MulterError
|
28
express-server/node_modules/multer/lib/remove-uploaded-files.js
generated
vendored
Normal file
28
express-server/node_modules/multer/lib/remove-uploaded-files.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
function removeUploadedFiles (uploadedFiles, remove, cb) {
|
||||
var length = uploadedFiles.length
|
||||
var errors = []
|
||||
|
||||
if (length === 0) return cb(null, errors)
|
||||
|
||||
function handleFile (idx) {
|
||||
var file = uploadedFiles[idx]
|
||||
|
||||
remove(file, function (err) {
|
||||
if (err) {
|
||||
err.file = file
|
||||
err.field = file.fieldname
|
||||
errors.push(err)
|
||||
}
|
||||
|
||||
if (idx < length - 1) {
|
||||
handleFile(idx + 1)
|
||||
} else {
|
||||
cb(null, errors)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
handleFile(0)
|
||||
}
|
||||
|
||||
module.exports = removeUploadedFiles
|
95
express-server/node_modules/multer/package.json
generated
vendored
Normal file
95
express-server/node_modules/multer/package.json
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
{
|
||||
"_from": "multer",
|
||||
"_id": "multer@1.4.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw==",
|
||||
"_location": "/multer",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "multer",
|
||||
"name": "multer",
|
||||
"escapedName": "multer",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/multer/-/multer-1.4.1.tgz",
|
||||
"_shasum": "24b12a416a22fec2ade810539184bf138720159e",
|
||||
"_spec": "multer",
|
||||
"_where": "D:\\5CHITM\\Diplomarbeit\\repos\\SmartShopper\\express-server",
|
||||
"bugs": {
|
||||
"url": "https://github.com/expressjs/multer/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Hage Yaapa",
|
||||
"email": "captain@hacksparrow.com",
|
||||
"url": "http://www.hacksparrow.com"
|
||||
},
|
||||
{
|
||||
"name": "Jaret Pfluger",
|
||||
"email": "https://github.com/jpfluger"
|
||||
},
|
||||
{
|
||||
"name": "Linus Unnebäck",
|
||||
"email": "linus@folkdatorn.se"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^0.2.11",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"on-finished": "^2.3.0",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Middleware for handling `multipart/form-data`.",
|
||||
"devDependencies": {
|
||||
"express": "^4.13.1",
|
||||
"form-data": "^1.0.0-rc1",
|
||||
"fs-temp": "^1.1.2",
|
||||
"mocha": "^3.5.3",
|
||||
"rimraf": "^2.4.1",
|
||||
"standard": "^11.0.1",
|
||||
"testdata-w3c-json-form": "^0.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"index.js",
|
||||
"storage/",
|
||||
"lib/"
|
||||
],
|
||||
"homepage": "https://github.com/expressjs/multer#readme",
|
||||
"keywords": [
|
||||
"form",
|
||||
"post",
|
||||
"multipart",
|
||||
"form-data",
|
||||
"formdata",
|
||||
"express",
|
||||
"middleware"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "multer",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/expressjs/multer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && mocha"
|
||||
},
|
||||
"version": "1.4.1"
|
||||
}
|
66
express-server/node_modules/multer/storage/disk.js
generated
vendored
Normal file
66
express-server/node_modules/multer/storage/disk.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
var fs = require('fs')
|
||||
var os = require('os')
|
||||
var path = require('path')
|
||||
var crypto = require('crypto')
|
||||
var mkdirp = require('mkdirp')
|
||||
|
||||
function getFilename (req, file, cb) {
|
||||
crypto.pseudoRandomBytes(16, function (err, raw) {
|
||||
cb(err, err ? undefined : raw.toString('hex'))
|
||||
})
|
||||
}
|
||||
|
||||
function getDestination (req, file, cb) {
|
||||
cb(null, os.tmpdir())
|
||||
}
|
||||
|
||||
function DiskStorage (opts) {
|
||||
this.getFilename = (opts.filename || getFilename)
|
||||
|
||||
if (typeof opts.destination === 'string') {
|
||||
mkdirp.sync(opts.destination)
|
||||
this.getDestination = function ($0, $1, cb) { cb(null, opts.destination) }
|
||||
} else {
|
||||
this.getDestination = (opts.destination || getDestination)
|
||||
}
|
||||
}
|
||||
|
||||
DiskStorage.prototype._handleFile = function _handleFile (req, file, cb) {
|
||||
var that = this
|
||||
|
||||
that.getDestination(req, file, function (err, destination) {
|
||||
if (err) return cb(err)
|
||||
|
||||
that.getFilename(req, file, function (err, filename) {
|
||||
if (err) return cb(err)
|
||||
|
||||
var finalPath = path.join(destination, filename)
|
||||
var outStream = fs.createWriteStream(finalPath)
|
||||
|
||||
file.stream.pipe(outStream)
|
||||
outStream.on('error', cb)
|
||||
outStream.on('finish', function () {
|
||||
cb(null, {
|
||||
destination: destination,
|
||||
filename: filename,
|
||||
path: finalPath,
|
||||
size: outStream.bytesWritten
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
DiskStorage.prototype._removeFile = function _removeFile (req, file, cb) {
|
||||
var path = file.path
|
||||
|
||||
delete file.destination
|
||||
delete file.filename
|
||||
delete file.path
|
||||
|
||||
fs.unlink(path, cb)
|
||||
}
|
||||
|
||||
module.exports = function (opts) {
|
||||
return new DiskStorage(opts)
|
||||
}
|
21
express-server/node_modules/multer/storage/memory.js
generated
vendored
Normal file
21
express-server/node_modules/multer/storage/memory.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
var concat = require('concat-stream')
|
||||
|
||||
function MemoryStorage (opts) {}
|
||||
|
||||
MemoryStorage.prototype._handleFile = function _handleFile (req, file, cb) {
|
||||
file.stream.pipe(concat({ encoding: 'buffer' }, function (data) {
|
||||
cb(null, {
|
||||
buffer: data,
|
||||
size: data.length
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
MemoryStorage.prototype._removeFile = function _removeFile (req, file, cb) {
|
||||
delete file.buffer
|
||||
cb(null)
|
||||
}
|
||||
|
||||
module.exports = function (opts) {
|
||||
return new MemoryStorage(opts)
|
||||
}
|
Reference in New Issue
Block a user