commit
This commit is contained in:
parent
cd1381db39
commit
ea7979b55b
171 changed files with 15742 additions and 0 deletions
1
node_modules/.bin/mkdirp
generated
vendored
Symbolic link
1
node_modules/.bin/mkdirp
generated
vendored
Symbolic link
|
@ -0,0 +1 @@
|
|||
../mkdirp/bin/cmd.js
|
1
node_modules/append-field/.npmignore
generated
vendored
Normal file
1
node_modules/append-field/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules/
|
21
node_modules/append-field/LICENSE
generated
vendored
Normal file
21
node_modules/append-field/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Linus Unnebäck
|
||||
|
||||
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.
|
44
node_modules/append-field/README.md
generated
vendored
Normal file
44
node_modules/append-field/README.md
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
# `append-field`
|
||||
|
||||
A [W3C HTML JSON forms spec](http://www.w3.org/TR/html-json-forms/) compliant
|
||||
field appender (for lack of a better name). Useful for people implementing
|
||||
`application/x-www-form-urlencoded` and `multipart/form-data` parsers.
|
||||
|
||||
It works best on objects created with `Object.create(null)`. Otherwise it might
|
||||
conflict with variables from the prototype (e.g. `hasOwnProperty`).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save append-field
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var appendField = require('append-field')
|
||||
var obj = Object.create(null)
|
||||
|
||||
appendField(obj, 'pets[0][species]', 'Dahut')
|
||||
appendField(obj, 'pets[0][name]', 'Hypatia')
|
||||
appendField(obj, 'pets[1][species]', 'Felis Stultus')
|
||||
appendField(obj, 'pets[1][name]', 'Billie')
|
||||
|
||||
console.log(obj)
|
||||
```
|
||||
|
||||
```text
|
||||
{ pets:
|
||||
[ { species: 'Dahut', name: 'Hypatia' },
|
||||
{ species: 'Felis Stultus', name: 'Billie' } ] }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `appendField(store, key, value)`
|
||||
|
||||
Adds the field named `key` with the value `value` to the object `store`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
12
node_modules/append-field/index.js
generated
vendored
Normal file
12
node_modules/append-field/index.js
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
var parsePath = require('./lib/parse-path')
|
||||
var setValue = require('./lib/set-value')
|
||||
|
||||
function appendField (store, key, value) {
|
||||
var steps = parsePath(key)
|
||||
|
||||
steps.reduce(function (context, step) {
|
||||
return setValue(context, step, context[step.key], value)
|
||||
}, store)
|
||||
}
|
||||
|
||||
module.exports = appendField
|
53
node_modules/append-field/lib/parse-path.js
generated
vendored
Normal file
53
node_modules/append-field/lib/parse-path.js
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
var reFirstKey = /^[^\[]*/
|
||||
var reDigitPath = /^\[(\d+)\]/
|
||||
var reNormalPath = /^\[([^\]]+)\]/
|
||||
|
||||
function parsePath (key) {
|
||||
function failure () {
|
||||
return [{ type: 'object', key: key, last: true }]
|
||||
}
|
||||
|
||||
var firstKey = reFirstKey.exec(key)[0]
|
||||
if (!firstKey) return failure()
|
||||
|
||||
var len = key.length
|
||||
var pos = firstKey.length
|
||||
var tail = { type: 'object', key: firstKey }
|
||||
var steps = [tail]
|
||||
|
||||
while (pos < len) {
|
||||
var m
|
||||
|
||||
if (key[pos] === '[' && key[pos + 1] === ']') {
|
||||
pos += 2
|
||||
tail.append = true
|
||||
if (pos !== len) return failure()
|
||||
continue
|
||||
}
|
||||
|
||||
m = reDigitPath.exec(key.substring(pos))
|
||||
if (m !== null) {
|
||||
pos += m[0].length
|
||||
tail.nextType = 'array'
|
||||
tail = { type: 'array', key: parseInt(m[1], 10) }
|
||||
steps.push(tail)
|
||||
continue
|
||||
}
|
||||
|
||||
m = reNormalPath.exec(key.substring(pos))
|
||||
if (m !== null) {
|
||||
pos += m[0].length
|
||||
tail.nextType = 'object'
|
||||
tail = { type: 'object', key: m[1] }
|
||||
steps.push(tail)
|
||||
continue
|
||||
}
|
||||
|
||||
return failure()
|
||||
}
|
||||
|
||||
tail.last = true
|
||||
return steps
|
||||
}
|
||||
|
||||
module.exports = parsePath
|
64
node_modules/append-field/lib/set-value.js
generated
vendored
Normal file
64
node_modules/append-field/lib/set-value.js
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
function valueType (value) {
|
||||
if (value === undefined) return 'undefined'
|
||||
if (Array.isArray(value)) return 'array'
|
||||
if (typeof value === 'object') return 'object'
|
||||
return 'scalar'
|
||||
}
|
||||
|
||||
function setLastValue (context, step, currentValue, entryValue) {
|
||||
switch (valueType(currentValue)) {
|
||||
case 'undefined':
|
||||
if (step.append) {
|
||||
context[step.key] = [entryValue]
|
||||
} else {
|
||||
context[step.key] = entryValue
|
||||
}
|
||||
break
|
||||
case 'array':
|
||||
context[step.key].push(entryValue)
|
||||
break
|
||||
case 'object':
|
||||
return setLastValue(currentValue, { type: 'object', key: '', last: true }, currentValue[''], entryValue)
|
||||
case 'scalar':
|
||||
context[step.key] = [context[step.key], entryValue]
|
||||
break
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
function setValue (context, step, currentValue, entryValue) {
|
||||
if (step.last) return setLastValue(context, step, currentValue, entryValue)
|
||||
|
||||
var obj
|
||||
switch (valueType(currentValue)) {
|
||||
case 'undefined':
|
||||
if (step.nextType === 'array') {
|
||||
context[step.key] = []
|
||||
} else {
|
||||
context[step.key] = Object.create(null)
|
||||
}
|
||||
return context[step.key]
|
||||
case 'object':
|
||||
return context[step.key]
|
||||
case 'array':
|
||||
if (step.nextType === 'array') {
|
||||
return currentValue
|
||||
}
|
||||
|
||||
obj = Object.create(null)
|
||||
context[step.key] = obj
|
||||
currentValue.forEach(function (item, i) {
|
||||
if (item !== undefined) obj['' + i] = item
|
||||
})
|
||||
|
||||
return obj
|
||||
case 'scalar':
|
||||
obj = Object.create(null)
|
||||
obj[''] = currentValue
|
||||
context[step.key] = obj
|
||||
return obj
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = setValue
|
19
node_modules/append-field/package.json
generated
vendored
Normal file
19
node_modules/append-field/package.json
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "append-field",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"author": "Linus Unnebäck <linus@folkdatorn.se>",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"mocha": "^2.2.4",
|
||||
"standard": "^6.0.5",
|
||||
"testdata-w3c-json-form": "^0.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "standard && mocha"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/LinusU/node-append-field.git"
|
||||
}
|
||||
}
|
19
node_modules/append-field/test/forms.js
generated
vendored
Normal file
19
node_modules/append-field/test/forms.js
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* eslint-env mocha */
|
||||
|
||||
var assert = require('assert')
|
||||
var appendField = require('../')
|
||||
var testData = require('testdata-w3c-json-form')
|
||||
|
||||
describe('Append Field', function () {
|
||||
for (var test of testData) {
|
||||
it('handles ' + test.name, function () {
|
||||
var store = Object.create(null)
|
||||
|
||||
for (var field of test.fields) {
|
||||
appendField(store, field.key, field.value)
|
||||
}
|
||||
|
||||
assert.deepEqual(store, test.expected)
|
||||
})
|
||||
}
|
||||
})
|
21
node_modules/buffer-from/LICENSE
generated
vendored
Normal file
21
node_modules/buffer-from/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016, 2018 Linus Unnebäck
|
||||
|
||||
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.
|
72
node_modules/buffer-from/index.js
generated
vendored
Normal file
72
node_modules/buffer-from/index.js
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* eslint-disable node/no-deprecated-api */
|
||||
|
||||
var toString = Object.prototype.toString
|
||||
|
||||
var isModern = (
|
||||
typeof Buffer !== 'undefined' &&
|
||||
typeof Buffer.alloc === 'function' &&
|
||||
typeof Buffer.allocUnsafe === 'function' &&
|
||||
typeof Buffer.from === 'function'
|
||||
)
|
||||
|
||||
function isArrayBuffer (input) {
|
||||
return toString.call(input).slice(8, -1) === 'ArrayBuffer'
|
||||
}
|
||||
|
||||
function fromArrayBuffer (obj, byteOffset, length) {
|
||||
byteOffset >>>= 0
|
||||
|
||||
var maxLength = obj.byteLength - byteOffset
|
||||
|
||||
if (maxLength < 0) {
|
||||
throw new RangeError("'offset' is out of bounds")
|
||||
}
|
||||
|
||||
if (length === undefined) {
|
||||
length = maxLength
|
||||
} else {
|
||||
length >>>= 0
|
||||
|
||||
if (length > maxLength) {
|
||||
throw new RangeError("'length' is out of bounds")
|
||||
}
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(obj.slice(byteOffset, byteOffset + length))
|
||||
: new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
|
||||
}
|
||||
|
||||
function fromString (string, encoding) {
|
||||
if (typeof encoding !== 'string' || encoding === '') {
|
||||
encoding = 'utf8'
|
||||
}
|
||||
|
||||
if (!Buffer.isEncoding(encoding)) {
|
||||
throw new TypeError('"encoding" must be a valid string encoding')
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(string, encoding)
|
||||
: new Buffer(string, encoding)
|
||||
}
|
||||
|
||||
function bufferFrom (value, encodingOrOffset, length) {
|
||||
if (typeof value === 'number') {
|
||||
throw new TypeError('"value" argument must not be a number')
|
||||
}
|
||||
|
||||
if (isArrayBuffer(value)) {
|
||||
return fromArrayBuffer(value, encodingOrOffset, length)
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return fromString(value, encodingOrOffset)
|
||||
}
|
||||
|
||||
return isModern
|
||||
? Buffer.from(value)
|
||||
: new Buffer(value)
|
||||
}
|
||||
|
||||
module.exports = bufferFrom
|
19
node_modules/buffer-from/package.json
generated
vendored
Normal file
19
node_modules/buffer-from/package.json
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "buffer-from",
|
||||
"version": "1.1.2",
|
||||
"license": "MIT",
|
||||
"repository": "LinusU/buffer-from",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "standard && node test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"standard": "^12.0.1"
|
||||
},
|
||||
"keywords": [
|
||||
"buffer",
|
||||
"buffer from"
|
||||
]
|
||||
}
|
69
node_modules/buffer-from/readme.md
generated
vendored
Normal file
69
node_modules/buffer-from/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Buffer From
|
||||
|
||||
A [ponyfill](https://ponyfill.com) for `Buffer.from`, uses native implementation if available.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save buffer-from
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const bufferFrom = require('buffer-from')
|
||||
|
||||
console.log(bufferFrom([1, 2, 3, 4]))
|
||||
//=> <Buffer 01 02 03 04>
|
||||
|
||||
const arr = new Uint8Array([1, 2, 3, 4])
|
||||
console.log(bufferFrom(arr.buffer, 1, 2))
|
||||
//=> <Buffer 02 03>
|
||||
|
||||
console.log(bufferFrom('test', 'utf8'))
|
||||
//=> <Buffer 74 65 73 74>
|
||||
|
||||
const buf = bufferFrom('test')
|
||||
console.log(bufferFrom(buf))
|
||||
//=> <Buffer 74 65 73 74>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### bufferFrom(array)
|
||||
|
||||
- `array` <Array>
|
||||
|
||||
Allocates a new `Buffer` using an `array` of octets.
|
||||
|
||||
### bufferFrom(arrayBuffer[, byteOffset[, length]])
|
||||
|
||||
- `arrayBuffer` <ArrayBuffer> The `.buffer` property of a TypedArray or ArrayBuffer
|
||||
- `byteOffset` <Integer> Where to start copying from `arrayBuffer`. **Default:** `0`
|
||||
- `length` <Integer> How many bytes to copy from `arrayBuffer`. **Default:** `arrayBuffer.length - byteOffset`
|
||||
|
||||
When passed a reference to the `.buffer` property of a TypedArray instance, the
|
||||
newly created `Buffer` will share the same allocated memory as the TypedArray.
|
||||
|
||||
The optional `byteOffset` and `length` arguments specify a memory range within
|
||||
the `arrayBuffer` that will be shared by the `Buffer`.
|
||||
|
||||
### bufferFrom(buffer)
|
||||
|
||||
- `buffer` <Buffer> An existing `Buffer` to copy data from
|
||||
|
||||
Copies the passed `buffer` data onto a new `Buffer` instance.
|
||||
|
||||
### bufferFrom(string[, encoding])
|
||||
|
||||
- `string` <String> A string to encode.
|
||||
- `encoding` <String> The encoding of `string`. **Default:** `'utf8'`
|
||||
|
||||
Creates a new `Buffer` containing the given JavaScript string `string`. If
|
||||
provided, the `encoding` parameter identifies the character encoding of
|
||||
`string`.
|
||||
|
||||
## See also
|
||||
|
||||
- [buffer-alloc](https://github.com/LinusU/buffer-alloc) A ponyfill for `Buffer.alloc`
|
||||
- [buffer-alloc-unsafe](https://github.com/LinusU/buffer-alloc-unsafe) A ponyfill for `Buffer.allocUnsafe`
|
5
node_modules/busboy/.eslintrc.js
generated
vendored
Normal file
5
node_modules/busboy/.eslintrc.js
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
extends: '@mscdex/eslint-config',
|
||||
};
|
24
node_modules/busboy/.github/workflows/ci.yml
generated
vendored
Normal file
24
node_modules/busboy/.github/workflows/ci.yml
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
tests-linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [10.16.0, 10.x, 12.x, 14.x, 16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install module
|
||||
run: npm install
|
||||
- name: Run tests
|
||||
run: npm test
|
23
node_modules/busboy/.github/workflows/lint.yml
generated
vendored
Normal file
23
node_modules/busboy/.github/workflows/lint.yml
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
name: lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
NODE_VERSION: 16.x
|
||||
|
||||
jobs:
|
||||
lint-js:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- name: Install ESLint + ESLint configs/plugins
|
||||
run: npm install --only=dev
|
||||
- name: Lint files
|
||||
run: npm run lint
|
19
node_modules/busboy/LICENSE
generated
vendored
Normal file
19
node_modules/busboy/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright Brian White. All rights reserved.
|
||||
|
||||
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.
|
191
node_modules/busboy/README.md
generated
vendored
Normal file
191
node_modules/busboy/README.md
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
# Description
|
||||
|
||||
A node.js module for parsing incoming HTML form data.
|
||||
|
||||
Changes (breaking or otherwise) in v1.0.0 can be found [here](https://github.com/mscdex/busboy/issues/266).
|
||||
|
||||
# Requirements
|
||||
|
||||
* [node.js](http://nodejs.org/) -- v10.16.0 or newer
|
||||
|
||||
|
||||
# Install
|
||||
|
||||
npm install busboy
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
* Parsing (multipart) with default options:
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
|
||||
const busboy = require('busboy');
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'POST') {
|
||||
console.log('POST request');
|
||||
const bb = busboy({ headers: req.headers });
|
||||
bb.on('file', (name, file, info) => {
|
||||
const { filename, encoding, mimeType } = info;
|
||||
console.log(
|
||||
`File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
|
||||
filename,
|
||||
encoding,
|
||||
mimeType
|
||||
);
|
||||
file.on('data', (data) => {
|
||||
console.log(`File [${name}] got ${data.length} bytes`);
|
||||
}).on('close', () => {
|
||||
console.log(`File [${name}] done`);
|
||||
});
|
||||
});
|
||||
bb.on('field', (name, val, info) => {
|
||||
console.log(`Field [${name}]: value: %j`, val);
|
||||
});
|
||||
bb.on('close', () => {
|
||||
console.log('Done parsing form!');
|
||||
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||
res.end();
|
||||
});
|
||||
req.pipe(bb);
|
||||
} else if (req.method === 'GET') {
|
||||
res.writeHead(200, { Connection: 'close' });
|
||||
res.end(`
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<input type="file" name="filefield"><br />
|
||||
<input type="text" name="textfield"><br />
|
||||
<input type="submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
}
|
||||
}).listen(8000, () => {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
|
||||
// Example output:
|
||||
//
|
||||
// Listening for requests
|
||||
// < ... form submitted ... >
|
||||
// POST request
|
||||
// File [filefield]: filename: "logo.jpg", encoding: "binary", mime: "image/jpeg"
|
||||
// File [filefield] got 11912 bytes
|
||||
// Field [textfield]: value: "testing! :-)"
|
||||
// File [filefield] done
|
||||
// Done parsing form!
|
||||
```
|
||||
|
||||
* Save all incoming files to disk:
|
||||
|
||||
```js
|
||||
const { randomFillSync } = require('crypto');
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
|
||||
const busboy = require('busboy');
|
||||
|
||||
const random = (() => {
|
||||
const buf = Buffer.alloc(16);
|
||||
return () => randomFillSync(buf).toString('hex');
|
||||
})();
|
||||
|
||||
http.createServer((req, res) => {
|
||||
if (req.method === 'POST') {
|
||||
const bb = busboy({ headers: req.headers });
|
||||
bb.on('file', (name, file, info) => {
|
||||
const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
|
||||
file.pipe(fs.createWriteStream(saveTo));
|
||||
});
|
||||
bb.on('close', () => {
|
||||
res.writeHead(200, { 'Connection': 'close' });
|
||||
res.end(`That's all folks!`);
|
||||
});
|
||||
req.pipe(bb);
|
||||
return;
|
||||
}
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}).listen(8000, () => {
|
||||
console.log('Listening for requests');
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
# API
|
||||
|
||||
## Exports
|
||||
|
||||
`busboy` exports a single function:
|
||||
|
||||
**( _function_ )**(< _object_ >config) - Creates and returns a new _Writable_ form parser stream.
|
||||
|
||||
* Valid `config` properties:
|
||||
|
||||
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
|
||||
|
||||
* **highWaterMark** - _integer_ - highWaterMark to use for the parser stream. **Default:** node's _stream.Writable_ default.
|
||||
|
||||
* **fileHwm** - _integer_ - highWaterMark to use for individual file streams. **Default:** node's _stream.Readable_ default.
|
||||
|
||||
* **defCharset** - _string_ - Default character set to use when one isn't defined. **Default:** `'utf8'`.
|
||||
|
||||
* **defParamCharset** - _string_ - For multipart forms, the default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). **Default:** `'latin1'`.
|
||||
|
||||
* **preservePath** - _boolean_ - If paths in filenames from file parts in a `'multipart/form-data'` request shall be preserved. **Default:** `false`.
|
||||
|
||||
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
|
||||
|
||||
* **fieldNameSize** - _integer_ - Max field name size (in bytes). **Default:** `100`.
|
||||
|
||||
* **fieldSize** - _integer_ - Max field value size (in bytes). **Default:** `1048576` (1MB).
|
||||
|
||||
* **fields** - _integer_ - Max number of non-file fields. **Default:** `Infinity`.
|
||||
|
||||
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes). **Default:** `Infinity`.
|
||||
|
||||
* **files** - _integer_ - For multipart forms, the max number of file fields. **Default:** `Infinity`.
|
||||
|
||||
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files). **Default:** `Infinity`.
|
||||
|
||||
* **headerPairs** - _integer_ - For multipart forms, the max number of header key-value pairs to parse. **Default:** `2000` (same as node's http module).
|
||||
|
||||
This function can throw exceptions if there is something wrong with the values in `config`. For example, if the Content-Type in `headers` is missing entirely, is not a supported type, or is missing the boundary for `'multipart/form-data'` requests.
|
||||
|
||||
## (Special) Parser stream events
|
||||
|
||||
* **file**(< _string_ >name, < _Readable_ >stream, < _object_ >info) - Emitted for each new file found. `name` contains the form field name. `stream` is a _Readable_ stream containing the file's data. No transformations/conversions (e.g. base64 to raw binary) are done on the file's data. `info` contains the following properties:
|
||||
|
||||
* `filename` - _string_ - If supplied, this contains the file's filename. **WARNING:** You should almost _never_ use this value as-is (especially if you are using `preservePath: true` in your `config`) as it could contain malicious input. You are better off generating your own (safe) filenames, or at the very least using a hash of the filename.
|
||||
|
||||
* `encoding` - _string_ - The file's `'Content-Transfer-Encoding'` value.
|
||||
|
||||
* `mimeType` - _string_ - The file's `'Content-Type'` value.
|
||||
|
||||
**Note:** If you listen for this event, you should always consume the `stream` whether you care about its contents or not (you can simply do `stream.resume();` if you want to discard/skip the contents), otherwise the `'finish'`/`'close'` event will never fire on the busboy parser stream.
|
||||
However, if you aren't accepting files, you can either simply not listen for the `'file'` event at all or set `limits.files` to `0`, and any/all files will be automatically skipped (these skipped files will still count towards any configured `limits.files` and `limits.parts` limits though).
|
||||
|
||||
**Note:** If a configured `limits.fileSize` limit was reached for a file, `stream` will both have a boolean property `truncated` set to `true` (best checked at the end of the stream) and emit a `'limit'` event to notify you when this happens.
|
||||
|
||||
* **field**(< _string_ >name, < _string_ >value, < _object_ >info) - Emitted for each new non-file field found. `name` contains the form field name. `value` contains the string value of the field. `info` contains the following properties:
|
||||
|
||||
* `nameTruncated` - _boolean_ - Whether `name` was truncated or not (due to a configured `limits.fieldNameSize` limit)
|
||||
|
||||
* `valueTruncated` - _boolean_ - Whether `value` was truncated or not (due to a configured `limits.fieldSize` limit)
|
||||
|
||||
* `encoding` - _string_ - The field's `'Content-Transfer-Encoding'` value.
|
||||
|
||||
* `mimeType` - _string_ - The field's `'Content-Type'` value.
|
||||
|
||||
* **partsLimit**() - Emitted when the configured `limits.parts` limit has been reached. No more `'file'` or `'field'` events will be emitted.
|
||||
|
||||
* **filesLimit**() - Emitted when the configured `limits.files` limit has been reached. No more `'file'` events will be emitted.
|
||||
|
||||
* **fieldsLimit**() - Emitted when the configured `limits.fields` limit has been reached. No more `'field'` events will be emitted.
|
149
node_modules/busboy/bench/bench-multipart-fields-100mb-big.js
generated
vendored
Normal file
149
node_modules/busboy/bench/bench-multipart-fields-100mb-big.js
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
'use strict';
|
||||
|
||||
function createMultipartBuffers(boundary, sizes) {
|
||||
const bufs = [];
|
||||
for (let i = 0; i < sizes.length; ++i) {
|
||||
const mb = sizes[i] * 1024 * 1024;
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}`,
|
||||
`content-disposition: form-data; name="field${i + 1}"`,
|
||||
'',
|
||||
'0'.repeat(mb),
|
||||
'',
|
||||
].join('\r\n')));
|
||||
}
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}--`,
|
||||
'',
|
||||
].join('\r\n')));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const boundary = '-----------------------------168072824752491622650073';
|
||||
const buffers = createMultipartBuffers(boundary, [
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
20,
|
||||
50,
|
||||
]);
|
||||
const calls = {
|
||||
partBegin: 0,
|
||||
headerField: 0,
|
||||
headerValue: 0,
|
||||
headerEnd: 0,
|
||||
headersEnd: 0,
|
||||
partData: 0,
|
||||
partEnd: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
});
|
||||
parser.on('field', (name, val, info) => {
|
||||
++calls.partBegin;
|
||||
++calls.partData;
|
||||
++calls.partEnd;
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const { MultipartParser } = require('formidable');
|
||||
|
||||
const parser = new MultipartParser();
|
||||
parser.initWithBoundary(boundary);
|
||||
parser.on('data', ({ name }) => {
|
||||
++calls[name];
|
||||
if (name === 'end')
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'multiparty': {
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const { Form } = require('multiparty');
|
||||
|
||||
const form = new Form({
|
||||
maxFieldsSize: Infinity,
|
||||
maxFields: Infinity,
|
||||
maxFilesSize: Infinity,
|
||||
autoFields: false,
|
||||
autoFiles: false,
|
||||
});
|
||||
|
||||
const req = new Readable({ read: () => {} });
|
||||
req.headers = {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
};
|
||||
|
||||
function hijack(name, fn) {
|
||||
const oldFn = form[name];
|
||||
form[name] = function() {
|
||||
fn();
|
||||
return oldFn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
hijack('onParseHeaderField', () => {
|
||||
++calls.headerField;
|
||||
});
|
||||
hijack('onParseHeaderValue', () => {
|
||||
++calls.headerValue;
|
||||
});
|
||||
hijack('onParsePartBegin', () => {
|
||||
++calls.partBegin;
|
||||
});
|
||||
hijack('onParsePartData', () => {
|
||||
++calls.partData;
|
||||
});
|
||||
hijack('onParsePartEnd', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
|
||||
form.on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
}).on('part', (p) => p.resume());
|
||||
|
||||
console.time(moduleName);
|
||||
form.parse(req);
|
||||
for (const buf of buffers)
|
||||
req.push(buf);
|
||||
req.push(null);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
143
node_modules/busboy/bench/bench-multipart-fields-100mb-small.js
generated
vendored
Normal file
143
node_modules/busboy/bench/bench-multipart-fields-100mb-small.js
generated
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
'use strict';
|
||||
|
||||
function createMultipartBuffers(boundary, sizes) {
|
||||
const bufs = [];
|
||||
for (let i = 0; i < sizes.length; ++i) {
|
||||
const mb = sizes[i] * 1024 * 1024;
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}`,
|
||||
`content-disposition: form-data; name="field${i + 1}"`,
|
||||
'',
|
||||
'0'.repeat(mb),
|
||||
'',
|
||||
].join('\r\n')));
|
||||
}
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}--`,
|
||||
'',
|
||||
].join('\r\n')));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const boundary = '-----------------------------168072824752491622650073';
|
||||
const buffers = createMultipartBuffers(boundary, (new Array(100)).fill(1));
|
||||
const calls = {
|
||||
partBegin: 0,
|
||||
headerField: 0,
|
||||
headerValue: 0,
|
||||
headerEnd: 0,
|
||||
headersEnd: 0,
|
||||
partData: 0,
|
||||
partEnd: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
});
|
||||
parser.on('field', (name, val, info) => {
|
||||
++calls.partBegin;
|
||||
++calls.partData;
|
||||
++calls.partEnd;
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const { MultipartParser } = require('formidable');
|
||||
|
||||
const parser = new MultipartParser();
|
||||
parser.initWithBoundary(boundary);
|
||||
parser.on('data', ({ name }) => {
|
||||
++calls[name];
|
||||
if (name === 'end')
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'multiparty': {
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const { Form } = require('multiparty');
|
||||
|
||||
const form = new Form({
|
||||
maxFieldsSize: Infinity,
|
||||
maxFields: Infinity,
|
||||
maxFilesSize: Infinity,
|
||||
autoFields: false,
|
||||
autoFiles: false,
|
||||
});
|
||||
|
||||
const req = new Readable({ read: () => {} });
|
||||
req.headers = {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
};
|
||||
|
||||
function hijack(name, fn) {
|
||||
const oldFn = form[name];
|
||||
form[name] = function() {
|
||||
fn();
|
||||
return oldFn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
hijack('onParseHeaderField', () => {
|
||||
++calls.headerField;
|
||||
});
|
||||
hijack('onParseHeaderValue', () => {
|
||||
++calls.headerValue;
|
||||
});
|
||||
hijack('onParsePartBegin', () => {
|
||||
++calls.partBegin;
|
||||
});
|
||||
hijack('onParsePartData', () => {
|
||||
++calls.partData;
|
||||
});
|
||||
hijack('onParsePartEnd', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
|
||||
form.on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
}).on('part', (p) => p.resume());
|
||||
|
||||
console.time(moduleName);
|
||||
form.parse(req);
|
||||
for (const buf of buffers)
|
||||
req.push(buf);
|
||||
req.push(null);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
154
node_modules/busboy/bench/bench-multipart-files-100mb-big.js
generated
vendored
Normal file
154
node_modules/busboy/bench/bench-multipart-files-100mb-big.js
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
'use strict';
|
||||
|
||||
function createMultipartBuffers(boundary, sizes) {
|
||||
const bufs = [];
|
||||
for (let i = 0; i < sizes.length; ++i) {
|
||||
const mb = sizes[i] * 1024 * 1024;
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}`,
|
||||
`content-disposition: form-data; name="file${i + 1}"; `
|
||||
+ `filename="random${i + 1}.bin"`,
|
||||
'content-type: application/octet-stream',
|
||||
'',
|
||||
'0'.repeat(mb),
|
||||
'',
|
||||
].join('\r\n')));
|
||||
}
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}--`,
|
||||
'',
|
||||
].join('\r\n')));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const boundary = '-----------------------------168072824752491622650073';
|
||||
const buffers = createMultipartBuffers(boundary, [
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
20,
|
||||
50,
|
||||
]);
|
||||
const calls = {
|
||||
partBegin: 0,
|
||||
headerField: 0,
|
||||
headerValue: 0,
|
||||
headerEnd: 0,
|
||||
headersEnd: 0,
|
||||
partData: 0,
|
||||
partEnd: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
});
|
||||
parser.on('file', (name, stream, info) => {
|
||||
++calls.partBegin;
|
||||
stream.on('data', (chunk) => {
|
||||
++calls.partData;
|
||||
}).on('end', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const { MultipartParser } = require('formidable');
|
||||
|
||||
const parser = new MultipartParser();
|
||||
parser.initWithBoundary(boundary);
|
||||
parser.on('data', ({ name }) => {
|
||||
++calls[name];
|
||||
if (name === 'end')
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'multiparty': {
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const { Form } = require('multiparty');
|
||||
|
||||
const form = new Form({
|
||||
maxFieldsSize: Infinity,
|
||||
maxFields: Infinity,
|
||||
maxFilesSize: Infinity,
|
||||
autoFields: false,
|
||||
autoFiles: false,
|
||||
});
|
||||
|
||||
const req = new Readable({ read: () => {} });
|
||||
req.headers = {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
};
|
||||
|
||||
function hijack(name, fn) {
|
||||
const oldFn = form[name];
|
||||
form[name] = function() {
|
||||
fn();
|
||||
return oldFn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
hijack('onParseHeaderField', () => {
|
||||
++calls.headerField;
|
||||
});
|
||||
hijack('onParseHeaderValue', () => {
|
||||
++calls.headerValue;
|
||||
});
|
||||
hijack('onParsePartBegin', () => {
|
||||
++calls.partBegin;
|
||||
});
|
||||
hijack('onParsePartData', () => {
|
||||
++calls.partData;
|
||||
});
|
||||
hijack('onParsePartEnd', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
|
||||
form.on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
}).on('part', (p) => p.resume());
|
||||
|
||||
console.time(moduleName);
|
||||
form.parse(req);
|
||||
for (const buf of buffers)
|
||||
req.push(buf);
|
||||
req.push(null);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
148
node_modules/busboy/bench/bench-multipart-files-100mb-small.js
generated
vendored
Normal file
148
node_modules/busboy/bench/bench-multipart-files-100mb-small.js
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
'use strict';
|
||||
|
||||
function createMultipartBuffers(boundary, sizes) {
|
||||
const bufs = [];
|
||||
for (let i = 0; i < sizes.length; ++i) {
|
||||
const mb = sizes[i] * 1024 * 1024;
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}`,
|
||||
`content-disposition: form-data; name="file${i + 1}"; `
|
||||
+ `filename="random${i + 1}.bin"`,
|
||||
'content-type: application/octet-stream',
|
||||
'',
|
||||
'0'.repeat(mb),
|
||||
'',
|
||||
].join('\r\n')));
|
||||
}
|
||||
bufs.push(Buffer.from([
|
||||
`--${boundary}--`,
|
||||
'',
|
||||
].join('\r\n')));
|
||||
return bufs;
|
||||
}
|
||||
|
||||
const boundary = '-----------------------------168072824752491622650073';
|
||||
const buffers = createMultipartBuffers(boundary, (new Array(100)).fill(1));
|
||||
const calls = {
|
||||
partBegin: 0,
|
||||
headerField: 0,
|
||||
headerValue: 0,
|
||||
headerEnd: 0,
|
||||
headersEnd: 0,
|
||||
partData: 0,
|
||||
partEnd: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
},
|
||||
});
|
||||
parser.on('file', (name, stream, info) => {
|
||||
++calls.partBegin;
|
||||
stream.on('data', (chunk) => {
|
||||
++calls.partData;
|
||||
}).on('end', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const { MultipartParser } = require('formidable');
|
||||
|
||||
const parser = new MultipartParser();
|
||||
parser.initWithBoundary(boundary);
|
||||
parser.on('data', ({ name }) => {
|
||||
++calls[name];
|
||||
if (name === 'end')
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
console.time(moduleName);
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'multiparty': {
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const { Form } = require('multiparty');
|
||||
|
||||
const form = new Form({
|
||||
maxFieldsSize: Infinity,
|
||||
maxFields: Infinity,
|
||||
maxFilesSize: Infinity,
|
||||
autoFields: false,
|
||||
autoFiles: false,
|
||||
});
|
||||
|
||||
const req = new Readable({ read: () => {} });
|
||||
req.headers = {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
};
|
||||
|
||||
function hijack(name, fn) {
|
||||
const oldFn = form[name];
|
||||
form[name] = function() {
|
||||
fn();
|
||||
return oldFn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
hijack('onParseHeaderField', () => {
|
||||
++calls.headerField;
|
||||
});
|
||||
hijack('onParseHeaderValue', () => {
|
||||
++calls.headerValue;
|
||||
});
|
||||
hijack('onParsePartBegin', () => {
|
||||
++calls.partBegin;
|
||||
});
|
||||
hijack('onParsePartData', () => {
|
||||
++calls.partData;
|
||||
});
|
||||
hijack('onParsePartEnd', () => {
|
||||
++calls.partEnd;
|
||||
});
|
||||
|
||||
form.on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
}).on('part', (p) => p.resume());
|
||||
|
||||
console.time(moduleName);
|
||||
form.parse(req);
|
||||
for (const buf of buffers)
|
||||
req.push(buf);
|
||||
req.push(null);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
101
node_modules/busboy/bench/bench-urlencoded-fields-100pairs-small.js
generated
vendored
Normal file
101
node_modules/busboy/bench/bench-urlencoded-fields-100pairs-small.js
generated
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
'use strict';
|
||||
|
||||
const buffers = [
|
||||
Buffer.from(
|
||||
(new Array(100)).fill('').map((_, i) => `key${i}=value${i}`).join('&')
|
||||
),
|
||||
];
|
||||
const calls = {
|
||||
field: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
let n = 3e3;
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
console.time(moduleName);
|
||||
(function next() {
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
},
|
||||
});
|
||||
parser.on('field', (name, val, info) => {
|
||||
++calls.field;
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
if (--n === 0)
|
||||
console.timeEnd(moduleName);
|
||||
else
|
||||
process.nextTick(next);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
})();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const QuerystringParser =
|
||||
require('formidable/src/parsers/Querystring.js');
|
||||
|
||||
console.time(moduleName);
|
||||
(function next() {
|
||||
const parser = new QuerystringParser();
|
||||
parser.on('data', (obj) => {
|
||||
++calls.field;
|
||||
}).on('end', () => {
|
||||
++calls.end;
|
||||
if (--n === 0)
|
||||
console.timeEnd(moduleName);
|
||||
else
|
||||
process.nextTick(next);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
})();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable-streaming': {
|
||||
const QuerystringParser =
|
||||
require('formidable/src/parsers/StreamingQuerystring.js');
|
||||
|
||||
console.time(moduleName);
|
||||
(function next() {
|
||||
const parser = new QuerystringParser();
|
||||
parser.on('data', (obj) => {
|
||||
++calls.field;
|
||||
}).on('end', () => {
|
||||
++calls.end;
|
||||
if (--n === 0)
|
||||
console.timeEnd(moduleName);
|
||||
else
|
||||
process.nextTick(next);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
})();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
84
node_modules/busboy/bench/bench-urlencoded-fields-900pairs-small-alt.js
generated
vendored
Normal file
84
node_modules/busboy/bench/bench-urlencoded-fields-900pairs-small-alt.js
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
const buffers = [
|
||||
Buffer.from(
|
||||
(new Array(900)).fill('').map((_, i) => `key${i}=value${i}`).join('&')
|
||||
),
|
||||
];
|
||||
const calls = {
|
||||
field: 0,
|
||||
end: 0,
|
||||
};
|
||||
|
||||
const moduleName = process.argv[2];
|
||||
switch (moduleName) {
|
||||
case 'busboy': {
|
||||
const busboy = require('busboy');
|
||||
|
||||
console.time(moduleName);
|
||||
const parser = busboy({
|
||||
limits: {
|
||||
fieldSizeLimit: Infinity,
|
||||
},
|
||||
headers: {
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
},
|
||||
});
|
||||
parser.on('field', (name, val, info) => {
|
||||
++calls.field;
|
||||
}).on('close', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable': {
|
||||
const QuerystringParser =
|
||||
require('formidable/src/parsers/Querystring.js');
|
||||
|
||||
console.time(moduleName);
|
||||
const parser = new QuerystringParser();
|
||||
parser.on('data', (obj) => {
|
||||
++calls.field;
|
||||
}).on('end', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
break;
|
||||
}
|
||||
|
||||
case 'formidable-streaming': {
|
||||
const QuerystringParser =
|
||||
require('formidable/src/parsers/StreamingQuerystring.js');
|
||||
|
||||
console.time(moduleName);
|
||||
const parser = new QuerystringParser();
|
||||
parser.on('data', (obj) => {
|
||||
++calls.field;
|
||||
}).on('end', () => {
|
||||
++calls.end;
|
||||
console.timeEnd(moduleName);
|
||||
});
|
||||
|
||||
for (const buf of buffers)
|
||||
parser.write(buf);
|
||||
parser.end();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (moduleName === undefined)
|
||||
console.error('Missing parser module name');
|
||||
else
|
||||
console.error(`Invalid parser module name: ${moduleName}`);
|
||||
process.exit(1);
|
||||
}
|
57
node_modules/busboy/lib/index.js
generated
vendored
Normal file
57
node_modules/busboy/lib/index.js
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
'use strict';
|
||||
|
||||
const { parseContentType } = require('./utils.js');
|
||||
|
||||
function getInstance(cfg) {
|
||||
const headers = cfg.headers;
|
||||
const conType = parseContentType(headers['content-type']);
|
||||
if (!conType)
|
||||
throw new Error('Malformed content type');
|
||||
|
||||
for (const type of TYPES) {
|
||||
const matched = type.detect(conType);
|
||||
if (!matched)
|
||||
continue;
|
||||
|
||||
const instanceCfg = {
|
||||
limits: cfg.limits,
|
||||
headers,
|
||||
conType,
|
||||
highWaterMark: undefined,
|
||||
fileHwm: undefined,
|
||||
defCharset: undefined,
|
||||
defParamCharset: undefined,
|
||||
preservePath: false,
|
||||
};
|
||||
if (cfg.highWaterMark)
|
||||
instanceCfg.highWaterMark = cfg.highWaterMark;
|
||||
if (cfg.fileHwm)
|
||||
instanceCfg.fileHwm = cfg.fileHwm;
|
||||
instanceCfg.defCharset = cfg.defCharset;
|
||||
instanceCfg.defParamCharset = cfg.defParamCharset;
|
||||
instanceCfg.preservePath = cfg.preservePath;
|
||||
return new type(instanceCfg);
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported content type: ${headers['content-type']}`);
|
||||
}
|
||||
|
||||
// Note: types are explicitly listed here for easier bundling
|
||||
// See: https://github.com/mscdex/busboy/issues/121
|
||||
const TYPES = [
|
||||
require('./types/multipart'),
|
||||
require('./types/urlencoded'),
|
||||
].filter(function(typemod) { return typeof typemod.detect === 'function'; });
|
||||
|
||||
module.exports = (cfg) => {
|
||||
if (typeof cfg !== 'object' || cfg === null)
|
||||
cfg = {};
|
||||
|
||||
if (typeof cfg.headers !== 'object'
|
||||
|| cfg.headers === null
|
||||
|| typeof cfg.headers['content-type'] !== 'string') {
|
||||
throw new Error('Missing Content-Type');
|
||||
}
|
||||
|
||||
return getInstance(cfg);
|
||||
};
|
653
node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
653
node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
|
@ -0,0 +1,653 @@
|
|||
'use strict';
|
||||
|
||||
const { Readable, Writable } = require('stream');
|
||||
|
||||
const StreamSearch = require('streamsearch');
|
||||
|
||||
const {
|
||||
basename,
|
||||
convertToUTF8,
|
||||
getDecoder,
|
||||
parseContentType,
|
||||
parseDisposition,
|
||||
} = require('../utils.js');
|
||||
|
||||
const BUF_CRLF = Buffer.from('\r\n');
|
||||
const BUF_CR = Buffer.from('\r');
|
||||
const BUF_DASH = Buffer.from('-');
|
||||
|
||||
function noop() {}
|
||||
|
||||
const MAX_HEADER_PAIRS = 2000; // From node
|
||||
const MAX_HEADER_SIZE = 16 * 1024; // From node (its default value)
|
||||
|
||||
const HPARSER_NAME = 0;
|
||||
const HPARSER_PRE_OWS = 1;
|
||||
const HPARSER_VALUE = 2;
|
||||
class HeaderParser {
|
||||
constructor(cb) {
|
||||
this.header = Object.create(null);
|
||||
this.pairCount = 0;
|
||||
this.byteCount = 0;
|
||||
this.state = HPARSER_NAME;
|
||||
this.name = '';
|
||||
this.value = '';
|
||||
this.crlf = 0;
|
||||
this.cb = cb;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.header = Object.create(null);
|
||||
this.pairCount = 0;
|
||||
this.byteCount = 0;
|
||||
this.state = HPARSER_NAME;
|
||||
this.name = '';
|
||||
this.value = '';
|
||||
this.crlf = 0;
|
||||
}
|
||||
|
||||
push(chunk, pos, end) {
|
||||
let start = pos;
|
||||
while (pos < end) {
|
||||
switch (this.state) {
|
||||
case HPARSER_NAME: {
|
||||
let done = false;
|
||||
for (; pos < end; ++pos) {
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
const code = chunk[pos];
|
||||
if (TOKEN[code] !== 1) {
|
||||
if (code !== 58/* ':' */)
|
||||
return -1;
|
||||
this.name += chunk.latin1Slice(start, pos);
|
||||
if (this.name.length === 0)
|
||||
return -1;
|
||||
++pos;
|
||||
done = true;
|
||||
this.state = HPARSER_PRE_OWS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
this.name += chunk.latin1Slice(start, pos);
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
}
|
||||
case HPARSER_PRE_OWS: {
|
||||
// Skip optional whitespace
|
||||
let done = false;
|
||||
for (; pos < end; ++pos) {
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
const code = chunk[pos];
|
||||
if (code !== 32/* ' ' */ && code !== 9/* '\t' */) {
|
||||
start = pos;
|
||||
done = true;
|
||||
this.state = HPARSER_VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
break;
|
||||
// FALLTHROUGH
|
||||
}
|
||||
case HPARSER_VALUE:
|
||||
switch (this.crlf) {
|
||||
case 0: // Nothing yet
|
||||
for (; pos < end; ++pos) {
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
const code = chunk[pos];
|
||||
if (FIELD_VCHAR[code] !== 1) {
|
||||
if (code !== 13/* '\r' */)
|
||||
return -1;
|
||||
++this.crlf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.value += chunk.latin1Slice(start, pos++);
|
||||
break;
|
||||
case 1: // Received CR
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
if (chunk[pos++] !== 10/* '\n' */)
|
||||
return -1;
|
||||
++this.crlf;
|
||||
break;
|
||||
case 2: { // Received CR LF
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
const code = chunk[pos];
|
||||
if (code === 32/* ' ' */ || code === 9/* '\t' */) {
|
||||
// Folded value
|
||||
start = pos;
|
||||
this.crlf = 0;
|
||||
} else {
|
||||
if (++this.pairCount < MAX_HEADER_PAIRS) {
|
||||
this.name = this.name.toLowerCase();
|
||||
if (this.header[this.name] === undefined)
|
||||
this.header[this.name] = [this.value];
|
||||
else
|
||||
this.header[this.name].push(this.value);
|
||||
}
|
||||
if (code === 13/* '\r' */) {
|
||||
++this.crlf;
|
||||
++pos;
|
||||
} else {
|
||||
// Assume start of next header field name
|
||||
start = pos;
|
||||
this.crlf = 0;
|
||||
this.state = HPARSER_NAME;
|
||||
this.name = '';
|
||||
this.value = '';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: { // Received CR LF CR
|
||||
if (this.byteCount === MAX_HEADER_SIZE)
|
||||
return -1;
|
||||
++this.byteCount;
|
||||
if (chunk[pos++] !== 10/* '\n' */)
|
||||
return -1;
|
||||
// End of header
|
||||
const header = this.header;
|
||||
this.reset();
|
||||
this.cb(header);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
class FileStream extends Readable {
|
||||
constructor(opts, owner) {
|
||||
super(opts);
|
||||
this.truncated = false;
|
||||
this._readcb = null;
|
||||
this.once('end', () => {
|
||||
// We need to make sure that we call any outstanding _writecb() that is
|
||||
// associated with this file so that processing of the rest of the form
|
||||
// can continue. This may not happen if the file stream ends right after
|
||||
// backpressure kicks in, so we force it here.
|
||||
this._read();
|
||||
if (--owner._fileEndsLeft === 0 && owner._finalcb) {
|
||||
const cb = owner._finalcb;
|
||||
owner._finalcb = null;
|
||||
// Make sure other 'end' event handlers get a chance to be executed
|
||||
// before busboy's 'finish' event is emitted
|
||||
process.nextTick(cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
_read(n) {
|
||||
const cb = this._readcb;
|
||||
if (cb) {
|
||||
this._readcb = null;
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ignoreData = {
|
||||
push: (chunk, pos) => {},
|
||||
destroy: () => {},
|
||||
};
|
||||
|
||||
function callAndUnsetCb(self, err) {
|
||||
const cb = self._writecb;
|
||||
self._writecb = null;
|
||||
if (err)
|
||||
self.destroy(err);
|
||||
else if (cb)
|
||||
cb();
|
||||
}
|
||||
|
||||
function nullDecoder(val, hint) {
|
||||
return val;
|
||||
}
|
||||
|
||||
class Multipart extends Writable {
|
||||
constructor(cfg) {
|
||||
const streamOpts = {
|
||||
autoDestroy: true,
|
||||
emitClose: true,
|
||||
highWaterMark: (typeof cfg.highWaterMark === 'number'
|
||||
? cfg.highWaterMark
|
||||
: undefined),
|
||||
};
|
||||
super(streamOpts);
|
||||
|
||||
if (!cfg.conType.params || typeof cfg.conType.params.boundary !== 'string')
|
||||
throw new Error('Multipart: Boundary not found');
|
||||
|
||||
const boundary = cfg.conType.params.boundary;
|
||||
const paramDecoder = (typeof cfg.defParamCharset === 'string'
|
||||
&& cfg.defParamCharset
|
||||
? getDecoder(cfg.defParamCharset)
|
||||
: nullDecoder);
|
||||
const defCharset = (cfg.defCharset || 'utf8');
|
||||
const preservePath = cfg.preservePath;
|
||||
const fileOpts = {
|
||||
autoDestroy: true,
|
||||
emitClose: true,
|
||||
highWaterMark: (typeof cfg.fileHwm === 'number'
|
||||
? cfg.fileHwm
|
||||
: undefined),
|
||||
};
|
||||
|
||||
const limits = cfg.limits;
|
||||
const fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||
? limits.fieldSize
|
||||
: 1 * 1024 * 1024);
|
||||
const fileSizeLimit = (limits && typeof limits.fileSize === 'number'
|
||||
? limits.fileSize
|
||||
: Infinity);
|
||||
const filesLimit = (limits && typeof limits.files === 'number'
|
||||
? limits.files
|
||||
: Infinity);
|
||||
const fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||
? limits.fields
|
||||
: Infinity);
|
||||
const partsLimit = (limits && typeof limits.parts === 'number'
|
||||
? limits.parts
|
||||
: Infinity);
|
||||
|
||||
let parts = -1; // Account for initial boundary
|
||||
let fields = 0;
|
||||
let files = 0;
|
||||
let skipPart = false;
|
||||
|
||||
this._fileEndsLeft = 0;
|
||||
this._fileStream = undefined;
|
||||
this._complete = false;
|
||||
let fileSize = 0;
|
||||
|
||||
let field;
|
||||
let fieldSize = 0;
|
||||
let partCharset;
|
||||
let partEncoding;
|
||||
let partType;
|
||||
let partName;
|
||||
let partTruncated = false;
|
||||
|
||||
let hitFilesLimit = false;
|
||||
let hitFieldsLimit = false;
|
||||
|
||||
this._hparser = null;
|
||||
const hparser = new HeaderParser((header) => {
|
||||
this._hparser = null;
|
||||
skipPart = false;
|
||||
|
||||
partType = 'text/plain';
|
||||
partCharset = defCharset;
|
||||
partEncoding = '7bit';
|
||||
partName = undefined;
|
||||
partTruncated = false;
|
||||
|
||||
let filename;
|
||||
if (!header['content-disposition']) {
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const disp = parseDisposition(header['content-disposition'][0],
|
||||
paramDecoder);
|
||||
if (!disp || disp.type !== 'form-data') {
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (disp.params) {
|
||||
if (disp.params.name)
|
||||
partName = disp.params.name;
|
||||
|
||||
if (disp.params['filename*'])
|
||||
filename = disp.params['filename*'];
|
||||
else if (disp.params.filename)
|
||||
filename = disp.params.filename;
|
||||
|
||||
if (filename !== undefined && !preservePath)
|
||||
filename = basename(filename);
|
||||
}
|
||||
|
||||
if (header['content-type']) {
|
||||
const conType = parseContentType(header['content-type'][0]);
|
||||
if (conType) {
|
||||
partType = `${conType.type}/${conType.subtype}`;
|
||||
if (conType.params && typeof conType.params.charset === 'string')
|
||||
partCharset = conType.params.charset.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
if (header['content-transfer-encoding'])
|
||||
partEncoding = header['content-transfer-encoding'][0].toLowerCase();
|
||||
|
||||
if (partType === 'application/octet-stream' || filename !== undefined) {
|
||||
// File
|
||||
|
||||
if (files === filesLimit) {
|
||||
if (!hitFilesLimit) {
|
||||
hitFilesLimit = true;
|
||||
this.emit('filesLimit');
|
||||
}
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
++files;
|
||||
|
||||
if (this.listenerCount('file') === 0) {
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
|
||||
fileSize = 0;
|
||||
this._fileStream = new FileStream(fileOpts, this);
|
||||
++this._fileEndsLeft;
|
||||
this.emit(
|
||||
'file',
|
||||
partName,
|
||||
this._fileStream,
|
||||
{ filename,
|
||||
encoding: partEncoding,
|
||||
mimeType: partType }
|
||||
);
|
||||
} else {
|
||||
// Non-file
|
||||
|
||||
if (fields === fieldsLimit) {
|
||||
if (!hitFieldsLimit) {
|
||||
hitFieldsLimit = true;
|
||||
this.emit('fieldsLimit');
|
||||
}
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
++fields;
|
||||
|
||||
if (this.listenerCount('field') === 0) {
|
||||
skipPart = true;
|
||||
return;
|
||||
}
|
||||
|
||||
field = [];
|
||||
fieldSize = 0;
|
||||
}
|
||||
});
|
||||
|
||||
let matchPostBoundary = 0;
|
||||
const ssCb = (isMatch, data, start, end, isDataSafe) => {
|
||||
retrydata:
|
||||
while (data) {
|
||||
if (this._hparser !== null) {
|
||||
const ret = this._hparser.push(data, start, end);
|
||||
if (ret === -1) {
|
||||
this._hparser = null;
|
||||
hparser.reset();
|
||||
this.emit('error', new Error('Malformed part header'));
|
||||
break;
|
||||
}
|
||||
start = ret;
|
||||
}
|
||||
|
||||
if (start === end)
|
||||
break;
|
||||
|
||||
if (matchPostBoundary !== 0) {
|
||||
if (matchPostBoundary === 1) {
|
||||
switch (data[start]) {
|
||||
case 45: // '-'
|
||||
// Try matching '--' after boundary
|
||||
matchPostBoundary = 2;
|
||||
++start;
|
||||
break;
|
||||
case 13: // '\r'
|
||||
// Try matching CR LF before header
|
||||
matchPostBoundary = 3;
|
||||
++start;
|
||||
break;
|
||||
default:
|
||||
matchPostBoundary = 0;
|
||||
}
|
||||
if (start === end)
|
||||
return;
|
||||
}
|
||||
|
||||
if (matchPostBoundary === 2) {
|
||||
matchPostBoundary = 0;
|
||||
if (data[start] === 45/* '-' */) {
|
||||
// End of multipart data
|
||||
this._complete = true;
|
||||
this._bparser = ignoreData;
|
||||
return;
|
||||
}
|
||||
// We saw something other than '-', so put the dash we consumed
|
||||
// "back"
|
||||
const writecb = this._writecb;
|
||||
this._writecb = noop;
|
||||
ssCb(false, BUF_DASH, 0, 1, false);
|
||||
this._writecb = writecb;
|
||||
} else if (matchPostBoundary === 3) {
|
||||
matchPostBoundary = 0;
|
||||
if (data[start] === 10/* '\n' */) {
|
||||
++start;
|
||||
if (parts >= partsLimit)
|
||||
break;
|
||||
// Prepare the header parser
|
||||
this._hparser = hparser;
|
||||
if (start === end)
|
||||
break;
|
||||
// Process the remaining data as a header
|
||||
continue retrydata;
|
||||
} else {
|
||||
// We saw something other than LF, so put the CR we consumed
|
||||
// "back"
|
||||
const writecb = this._writecb;
|
||||
this._writecb = noop;
|
||||
ssCb(false, BUF_CR, 0, 1, false);
|
||||
this._writecb = writecb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipPart) {
|
||||
if (this._fileStream) {
|
||||
let chunk;
|
||||
const actualLen = Math.min(end - start, fileSizeLimit - fileSize);
|
||||
if (!isDataSafe) {
|
||||
chunk = Buffer.allocUnsafe(actualLen);
|
||||
data.copy(chunk, 0, start, start + actualLen);
|
||||
} else {
|
||||
chunk = data.slice(start, start + actualLen);
|
||||
}
|
||||
|
||||
fileSize += chunk.length;
|
||||
if (fileSize === fileSizeLimit) {
|
||||
if (chunk.length > 0)
|
||||
this._fileStream.push(chunk);
|
||||
this._fileStream.emit('limit');
|
||||
this._fileStream.truncated = true;
|
||||
skipPart = true;
|
||||
} else if (!this._fileStream.push(chunk)) {
|
||||
if (this._writecb)
|
||||
this._fileStream._readcb = this._writecb;
|
||||
this._writecb = null;
|
||||
}
|
||||
} else if (field !== undefined) {
|
||||
let chunk;
|
||||
const actualLen = Math.min(
|
||||
end - start,
|
||||
fieldSizeLimit - fieldSize
|
||||
);
|
||||
if (!isDataSafe) {
|
||||
chunk = Buffer.allocUnsafe(actualLen);
|
||||
data.copy(chunk, 0, start, start + actualLen);
|
||||
} else {
|
||||
chunk = data.slice(start, start + actualLen);
|
||||
}
|
||||
|
||||
fieldSize += actualLen;
|
||||
field.push(chunk);
|
||||
if (fieldSize === fieldSizeLimit) {
|
||||
skipPart = true;
|
||||
partTruncated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (isMatch) {
|
||||
matchPostBoundary = 1;
|
||||
|
||||
if (this._fileStream) {
|
||||
// End the active file stream if the previous part was a file
|
||||
this._fileStream.push(null);
|
||||
this._fileStream = null;
|
||||
} else if (field !== undefined) {
|
||||
let data;
|
||||
switch (field.length) {
|
||||
case 0:
|
||||
data = '';
|
||||
break;
|
||||
case 1:
|
||||
data = convertToUTF8(field[0], partCharset, 0);
|
||||
break;
|
||||
default:
|
||||
data = convertToUTF8(
|
||||
Buffer.concat(field, fieldSize),
|
||||
partCharset,
|
||||
0
|
||||
);
|
||||
}
|
||||
field = undefined;
|
||||
fieldSize = 0;
|
||||
this.emit(
|
||||
'field',
|
||||
partName,
|
||||
data,
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: partTruncated,
|
||||
encoding: partEncoding,
|
||||
mimeType: partType }
|
||||
);
|
||||
}
|
||||
|
||||
if (++parts === partsLimit)
|
||||
this.emit('partsLimit');
|
||||
}
|
||||
};
|
||||
this._bparser = new StreamSearch(`\r\n--${boundary}`, ssCb);
|
||||
|
||||
this._writecb = null;
|
||||
this._finalcb = null;
|
||||
|
||||
// Just in case there is no preamble
|
||||
this.write(BUF_CRLF);
|
||||
}
|
||||
|
||||
static detect(conType) {
|
||||
return (conType.type === 'multipart' && conType.subtype === 'form-data');
|
||||
}
|
||||
|
||||
_write(chunk, enc, cb) {
|
||||
this._writecb = cb;
|
||||
this._bparser.push(chunk, 0);
|
||||
if (this._writecb)
|
||||
callAndUnsetCb(this);
|
||||
}
|
||||
|
||||
_destroy(err, cb) {
|
||||
this._hparser = null;
|
||||
this._bparser = ignoreData;
|
||||
if (!err)
|
||||
err = checkEndState(this);
|
||||
const fileStream = this._fileStream;
|
||||
if (fileStream) {
|
||||
this._fileStream = null;
|
||||
fileStream.destroy(err);
|
||||
}
|
||||
cb(err);
|
||||
}
|
||||
|
||||
_final(cb) {
|
||||
this._bparser.destroy();
|
||||
if (!this._complete)
|
||||
return cb(new Error('Unexpected end of form'));
|
||||
if (this._fileEndsLeft)
|
||||
this._finalcb = finalcb.bind(null, this, cb);
|
||||
else
|
||||
finalcb(this, cb);
|
||||
}
|
||||
}
|
||||
|
||||
function finalcb(self, cb, err) {
|
||||
if (err)
|
||||
return cb(err);
|
||||
err = checkEndState(self);
|
||||
cb(err);
|
||||
}
|
||||
|
||||
function checkEndState(self) {
|
||||
if (self._hparser)
|
||||
return new Error('Malformed part header');
|
||||
const fileStream = self._fileStream;
|
||||
if (fileStream) {
|
||||
self._fileStream = null;
|
||||
fileStream.destroy(new Error('Unexpected end of file'));
|
||||
}
|
||||
if (!self._complete)
|
||||
return new Error('Unexpected end of form');
|
||||
}
|
||||
|
||||
const TOKEN = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
const FIELD_VCHAR = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
];
|
||||
|
||||
module.exports = Multipart;
|
350
node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
350
node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
|
@ -0,0 +1,350 @@
|
|||
'use strict';
|
||||
|
||||
const { Writable } = require('stream');
|
||||
|
||||
const { getDecoder } = require('../utils.js');
|
||||
|
||||
class URLEncoded extends Writable {
|
||||
constructor(cfg) {
|
||||
const streamOpts = {
|
||||
autoDestroy: true,
|
||||
emitClose: true,
|
||||
highWaterMark: (typeof cfg.highWaterMark === 'number'
|
||||
? cfg.highWaterMark
|
||||
: undefined),
|
||||
};
|
||||
super(streamOpts);
|
||||
|
||||
let charset = (cfg.defCharset || 'utf8');
|
||||
if (cfg.conType.params && typeof cfg.conType.params.charset === 'string')
|
||||
charset = cfg.conType.params.charset;
|
||||
|
||||
this.charset = charset;
|
||||
|
||||
const limits = cfg.limits;
|
||||
this.fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||
? limits.fieldSize
|
||||
: 1 * 1024 * 1024);
|
||||
this.fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||
? limits.fields
|
||||
: Infinity);
|
||||
this.fieldNameSizeLimit = (
|
||||
limits && typeof limits.fieldNameSize === 'number'
|
||||
? limits.fieldNameSize
|
||||
: 100
|
||||
);
|
||||
|
||||
this._inKey = true;
|
||||
this._keyTrunc = false;
|
||||
this._valTrunc = false;
|
||||
this._bytesKey = 0;
|
||||
this._bytesVal = 0;
|
||||
this._fields = 0;
|
||||
this._key = '';
|
||||
this._val = '';
|
||||
this._byte = -2;
|
||||
this._lastPos = 0;
|
||||
this._encode = 0;
|
||||
this._decoder = getDecoder(charset);
|
||||
}
|
||||
|
||||
static detect(conType) {
|
||||
return (conType.type === 'application'
|
||||
&& conType.subtype === 'x-www-form-urlencoded');
|
||||
}
|
||||
|
||||
_write(chunk, enc, cb) {
|
||||
if (this._fields >= this.fieldsLimit)
|
||||
return cb();
|
||||
|
||||
let i = 0;
|
||||
const len = chunk.length;
|
||||
this._lastPos = 0;
|
||||
|
||||
// Check if we last ended mid-percent-encoded byte
|
||||
if (this._byte !== -2) {
|
||||
i = readPctEnc(this, chunk, i, len);
|
||||
if (i === -1)
|
||||
return cb(new Error('Malformed urlencoded form'));
|
||||
if (i >= len)
|
||||
return cb();
|
||||
if (this._inKey)
|
||||
++this._bytesKey;
|
||||
else
|
||||
++this._bytesVal;
|
||||
}
|
||||
|
||||
main:
|
||||
while (i < len) {
|
||||
if (this._inKey) {
|
||||
// Parsing key
|
||||
|
||||
i = skipKeyBytes(this, chunk, i, len);
|
||||
|
||||
while (i < len) {
|
||||
switch (chunk[i]) {
|
||||
case 61: // '='
|
||||
if (this._lastPos < i)
|
||||
this._key += chunk.latin1Slice(this._lastPos, i);
|
||||
this._lastPos = ++i;
|
||||
this._key = this._decoder(this._key, this._encode);
|
||||
this._encode = 0;
|
||||
this._inKey = false;
|
||||
continue main;
|
||||
case 38: // '&'
|
||||
if (this._lastPos < i)
|
||||
this._key += chunk.latin1Slice(this._lastPos, i);
|
||||
this._lastPos = ++i;
|
||||
this._key = this._decoder(this._key, this._encode);
|
||||
this._encode = 0;
|
||||
if (this._bytesKey > 0) {
|
||||
this.emit(
|
||||
'field',
|
||||
this._key,
|
||||
'',
|
||||
{ nameTruncated: this._keyTrunc,
|
||||
valueTruncated: false,
|
||||
encoding: this.charset,
|
||||
mimeType: 'text/plain' }
|
||||
);
|
||||
}
|
||||
this._key = '';
|
||||
this._val = '';
|
||||
this._keyTrunc = false;
|
||||
this._valTrunc = false;
|
||||
this._bytesKey = 0;
|
||||
this._bytesVal = 0;
|
||||
if (++this._fields >= this.fieldsLimit) {
|
||||
this.emit('fieldsLimit');
|
||||
return cb();
|
||||
}
|
||||
continue;
|
||||
case 43: // '+'
|
||||
if (this._lastPos < i)
|
||||
this._key += chunk.latin1Slice(this._lastPos, i);
|
||||
this._key += ' ';
|
||||
this._lastPos = i + 1;
|
||||
break;
|
||||
case 37: // '%'
|
||||
if (this._encode === 0)
|
||||
this._encode = 1;
|
||||
if (this._lastPos < i)
|
||||
this._key += chunk.latin1Slice(this._lastPos, i);
|
||||
this._lastPos = i + 1;
|
||||
this._byte = -1;
|
||||
i = readPctEnc(this, chunk, i + 1, len);
|
||||
if (i === -1)
|
||||
return cb(new Error('Malformed urlencoded form'));
|
||||
if (i >= len)
|
||||
return cb();
|
||||
++this._bytesKey;
|
||||
i = skipKeyBytes(this, chunk, i, len);
|
||||
continue;
|
||||
}
|
||||
++i;
|
||||
++this._bytesKey;
|
||||
i = skipKeyBytes(this, chunk, i, len);
|
||||
}
|
||||
if (this._lastPos < i)
|
||||
this._key += chunk.latin1Slice(this._lastPos, i);
|
||||
} else {
|
||||
// Parsing value
|
||||
|
||||
i = skipValBytes(this, chunk, i, len);
|
||||
|
||||
while (i < len) {
|
||||
switch (chunk[i]) {
|
||||
case 38: // '&'
|
||||
if (this._lastPos < i)
|
||||
this._val += chunk.latin1Slice(this._lastPos, i);
|
||||
this._lastPos = ++i;
|
||||
this._inKey = true;
|
||||
this._val = this._decoder(this._val, this._encode);
|
||||
this._encode = 0;
|
||||
if (this._bytesKey > 0 || this._bytesVal > 0) {
|
||||
this.emit(
|
||||
'field',
|
||||
this._key,
|
||||
this._val,
|
||||
{ nameTruncated: this._keyTrunc,
|
||||
valueTruncated: this._valTrunc,
|
||||
encoding: this.charset,
|
||||
mimeType: 'text/plain' }
|
||||
);
|
||||
}
|
||||
this._key = '';
|
||||
this._val = '';
|
||||
this._keyTrunc = false;
|
||||
this._valTrunc = false;
|
||||
this._bytesKey = 0;
|
||||
this._bytesVal = 0;
|
||||
if (++this._fields >= this.fieldsLimit) {
|
||||
this.emit('fieldsLimit');
|
||||
return cb();
|
||||
}
|
||||
continue main;
|
||||
case 43: // '+'
|
||||
if (this._lastPos < i)
|
||||
this._val += chunk.latin1Slice(this._lastPos, i);
|
||||
this._val += ' ';
|
||||
this._lastPos = i + 1;
|
||||
break;
|
||||
case 37: // '%'
|
||||
if (this._encode === 0)
|
||||
this._encode = 1;
|
||||
if (this._lastPos < i)
|
||||
this._val += chunk.latin1Slice(this._lastPos, i);
|
||||
this._lastPos = i + 1;
|
||||
this._byte = -1;
|
||||
i = readPctEnc(this, chunk, i + 1, len);
|
||||
if (i === -1)
|
||||
return cb(new Error('Malformed urlencoded form'));
|
||||
if (i >= len)
|
||||
return cb();
|
||||
++this._bytesVal;
|
||||
i = skipValBytes(this, chunk, i, len);
|
||||
continue;
|
||||
}
|
||||
++i;
|
||||
++this._bytesVal;
|
||||
i = skipValBytes(this, chunk, i, len);
|
||||
}
|
||||
if (this._lastPos < i)
|
||||
this._val += chunk.latin1Slice(this._lastPos, i);
|
||||
}
|
||||
}
|
||||
|
||||
cb();
|
||||
}
|
||||
|
||||
_final(cb) {
|
||||
if (this._byte !== -2)
|
||||
return cb(new Error('Malformed urlencoded form'));
|
||||
if (!this._inKey || this._bytesKey > 0 || this._bytesVal > 0) {
|
||||
if (this._inKey)
|
||||
this._key = this._decoder(this._key, this._encode);
|
||||
else
|
||||
this._val = this._decoder(this._val, this._encode);
|
||||
this.emit(
|
||||
'field',
|
||||
this._key,
|
||||
this._val,
|
||||
{ nameTruncated: this._keyTrunc,
|
||||
valueTruncated: this._valTrunc,
|
||||
encoding: this.charset,
|
||||
mimeType: 'text/plain' }
|
||||
);
|
||||
}
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
function readPctEnc(self, chunk, pos, len) {
|
||||
if (pos >= len)
|
||||
return len;
|
||||
|
||||
if (self._byte === -1) {
|
||||
// We saw a '%' but no hex characters yet
|
||||
const hexUpper = HEX_VALUES[chunk[pos++]];
|
||||
if (hexUpper === -1)
|
||||
return -1;
|
||||
|
||||
if (hexUpper >= 8)
|
||||
self._encode = 2; // Indicate high bits detected
|
||||
|
||||
if (pos < len) {
|
||||
// Both hex characters are in this chunk
|
||||
const hexLower = HEX_VALUES[chunk[pos++]];
|
||||
if (hexLower === -1)
|
||||
return -1;
|
||||
|
||||
if (self._inKey)
|
||||
self._key += String.fromCharCode((hexUpper << 4) + hexLower);
|
||||
else
|
||||
self._val += String.fromCharCode((hexUpper << 4) + hexLower);
|
||||
|
||||
self._byte = -2;
|
||||
self._lastPos = pos;
|
||||
} else {
|
||||
// Only one hex character was available in this chunk
|
||||
self._byte = hexUpper;
|
||||
}
|
||||
} else {
|
||||
// We saw only one hex character so far
|
||||
const hexLower = HEX_VALUES[chunk[pos++]];
|
||||
if (hexLower === -1)
|
||||
return -1;
|
||||
|
||||
if (self._inKey)
|
||||
self._key += String.fromCharCode((self._byte << 4) + hexLower);
|
||||
else
|
||||
self._val += String.fromCharCode((self._byte << 4) + hexLower);
|
||||
|
||||
self._byte = -2;
|
||||
self._lastPos = pos;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
function skipKeyBytes(self, chunk, pos, len) {
|
||||
// Skip bytes if we've truncated
|
||||
if (self._bytesKey > self.fieldNameSizeLimit) {
|
||||
if (!self._keyTrunc) {
|
||||
if (self._lastPos < pos)
|
||||
self._key += chunk.latin1Slice(self._lastPos, pos - 1);
|
||||
}
|
||||
self._keyTrunc = true;
|
||||
for (; pos < len; ++pos) {
|
||||
const code = chunk[pos];
|
||||
if (code === 61/* '=' */ || code === 38/* '&' */)
|
||||
break;
|
||||
++self._bytesKey;
|
||||
}
|
||||
self._lastPos = pos;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
function skipValBytes(self, chunk, pos, len) {
|
||||
// Skip bytes if we've truncated
|
||||
if (self._bytesVal > self.fieldSizeLimit) {
|
||||
if (!self._valTrunc) {
|
||||
if (self._lastPos < pos)
|
||||
self._val += chunk.latin1Slice(self._lastPos, pos - 1);
|
||||
}
|
||||
self._valTrunc = true;
|
||||
for (; pos < len; ++pos) {
|
||||
if (chunk[pos] === 38/* '&' */)
|
||||
break;
|
||||
++self._bytesVal;
|
||||
}
|
||||
self._lastPos = pos;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* eslint-disable no-multi-spaces */
|
||||
const HEX_VALUES = [
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
];
|
||||
/* eslint-enable no-multi-spaces */
|
||||
|
||||
module.exports = URLEncoded;
|
596
node_modules/busboy/lib/utils.js
generated
vendored
Normal file
596
node_modules/busboy/lib/utils.js
generated
vendored
Normal file
|
@ -0,0 +1,596 @@
|
|||
'use strict';
|
||||
|
||||
function parseContentType(str) {
|
||||
if (str.length === 0)
|
||||
return;
|
||||
|
||||
const params = Object.create(null);
|
||||
let i = 0;
|
||||
|
||||
// Parse type
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
if (code !== 47/* '/' */ || i === 0)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check for type without subtype
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
const type = str.slice(0, i).toLowerCase();
|
||||
|
||||
// Parse subtype
|
||||
const subtypeStart = ++i;
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
// Make sure we have a subtype
|
||||
if (i === subtypeStart)
|
||||
return;
|
||||
|
||||
if (parseContentTypeParams(str, i, params) === undefined)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Make sure we have a subtype
|
||||
if (i === subtypeStart)
|
||||
return;
|
||||
|
||||
const subtype = str.slice(subtypeStart, i).toLowerCase();
|
||||
|
||||
return { type, subtype, params };
|
||||
}
|
||||
|
||||
function parseContentTypeParams(str, i, params) {
|
||||
while (i < str.length) {
|
||||
// Consume whitespace
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
|
||||
break;
|
||||
}
|
||||
|
||||
// Ended on whitespace
|
||||
if (i === str.length)
|
||||
break;
|
||||
|
||||
// Check for malformed parameter
|
||||
if (str.charCodeAt(i++) !== 59/* ';' */)
|
||||
return;
|
||||
|
||||
// Consume whitespace
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
|
||||
break;
|
||||
}
|
||||
|
||||
// Ended on whitespace (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
let name;
|
||||
const nameStart = i;
|
||||
// Parse parameter name
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
if (code !== 61/* '=' */)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No value (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
name = str.slice(nameStart, i);
|
||||
++i; // Skip over '='
|
||||
|
||||
// No value (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
let value = '';
|
||||
let valueStart;
|
||||
if (str.charCodeAt(i) === 34/* '"' */) {
|
||||
valueStart = ++i;
|
||||
let escaping = false;
|
||||
// Parse quoted value
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code === 92/* '\\' */) {
|
||||
if (escaping) {
|
||||
valueStart = i;
|
||||
escaping = false;
|
||||
} else {
|
||||
value += str.slice(valueStart, i);
|
||||
escaping = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (code === 34/* '"' */) {
|
||||
if (escaping) {
|
||||
valueStart = i;
|
||||
escaping = false;
|
||||
continue;
|
||||
}
|
||||
value += str.slice(valueStart, i);
|
||||
break;
|
||||
}
|
||||
if (escaping) {
|
||||
valueStart = i - 1;
|
||||
escaping = false;
|
||||
}
|
||||
// Invalid unescaped quoted character (malformed)
|
||||
if (QDTEXT[code] !== 1)
|
||||
return;
|
||||
}
|
||||
|
||||
// No end quote (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
++i; // Skip over double quote
|
||||
} else {
|
||||
valueStart = i;
|
||||
// Parse unquoted value
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
// No value (malformed)
|
||||
if (i === valueStart)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = str.slice(valueStart, i);
|
||||
}
|
||||
|
||||
name = name.toLowerCase();
|
||||
if (params[name] === undefined)
|
||||
params[name] = value;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
function parseDisposition(str, defDecoder) {
|
||||
if (str.length === 0)
|
||||
return;
|
||||
|
||||
const params = Object.create(null);
|
||||
let i = 0;
|
||||
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
if (parseDispositionParams(str, i, params, defDecoder) === undefined)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const type = str.slice(0, i).toLowerCase();
|
||||
|
||||
return { type, params };
|
||||
}
|
||||
|
||||
function parseDispositionParams(str, i, params, defDecoder) {
|
||||
while (i < str.length) {
|
||||
// Consume whitespace
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
|
||||
break;
|
||||
}
|
||||
|
||||
// Ended on whitespace
|
||||
if (i === str.length)
|
||||
break;
|
||||
|
||||
// Check for malformed parameter
|
||||
if (str.charCodeAt(i++) !== 59/* ';' */)
|
||||
return;
|
||||
|
||||
// Consume whitespace
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
|
||||
break;
|
||||
}
|
||||
|
||||
// Ended on whitespace (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
let name;
|
||||
const nameStart = i;
|
||||
// Parse parameter name
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
if (code === 61/* '=' */)
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No value (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
let value = '';
|
||||
let valueStart;
|
||||
let charset;
|
||||
//~ let lang;
|
||||
name = str.slice(nameStart, i);
|
||||
if (name.charCodeAt(name.length - 1) === 42/* '*' */) {
|
||||
// Extended value
|
||||
|
||||
const charsetStart = ++i;
|
||||
// Parse charset name
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (CHARSET[code] !== 1) {
|
||||
if (code !== 39/* '\'' */)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Incomplete charset (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
charset = str.slice(charsetStart, i);
|
||||
++i; // Skip over the '\''
|
||||
|
||||
//~ const langStart = ++i;
|
||||
// Parse language name
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code === 39/* '\'' */)
|
||||
break;
|
||||
}
|
||||
|
||||
// Incomplete language (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
//~ lang = str.slice(langStart, i);
|
||||
++i; // Skip over the '\''
|
||||
|
||||
// No value (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
valueStart = i;
|
||||
|
||||
let encode = 0;
|
||||
// Parse value
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (EXTENDED_VALUE[code] !== 1) {
|
||||
if (code === 37/* '%' */) {
|
||||
let hexUpper;
|
||||
let hexLower;
|
||||
if (i + 2 < str.length
|
||||
&& (hexUpper = HEX_VALUES[str.charCodeAt(i + 1)]) !== -1
|
||||
&& (hexLower = HEX_VALUES[str.charCodeAt(i + 2)]) !== -1) {
|
||||
const byteVal = (hexUpper << 4) + hexLower;
|
||||
value += str.slice(valueStart, i);
|
||||
value += String.fromCharCode(byteVal);
|
||||
i += 2;
|
||||
valueStart = i + 1;
|
||||
if (byteVal >= 128)
|
||||
encode = 2;
|
||||
else if (encode === 0)
|
||||
encode = 1;
|
||||
continue;
|
||||
}
|
||||
// '%' disallowed in non-percent encoded contexts (malformed)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
value += str.slice(valueStart, i);
|
||||
value = convertToUTF8(value, charset, encode);
|
||||
if (value === undefined)
|
||||
return;
|
||||
} else {
|
||||
// Non-extended value
|
||||
|
||||
++i; // Skip over '='
|
||||
|
||||
// No value (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
if (str.charCodeAt(i) === 34/* '"' */) {
|
||||
valueStart = ++i;
|
||||
let escaping = false;
|
||||
// Parse quoted value
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code === 92/* '\\' */) {
|
||||
if (escaping) {
|
||||
valueStart = i;
|
||||
escaping = false;
|
||||
} else {
|
||||
value += str.slice(valueStart, i);
|
||||
escaping = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (code === 34/* '"' */) {
|
||||
if (escaping) {
|
||||
valueStart = i;
|
||||
escaping = false;
|
||||
continue;
|
||||
}
|
||||
value += str.slice(valueStart, i);
|
||||
break;
|
||||
}
|
||||
if (escaping) {
|
||||
valueStart = i - 1;
|
||||
escaping = false;
|
||||
}
|
||||
// Invalid unescaped quoted character (malformed)
|
||||
if (QDTEXT[code] !== 1)
|
||||
return;
|
||||
}
|
||||
|
||||
// No end quote (malformed)
|
||||
if (i === str.length)
|
||||
return;
|
||||
|
||||
++i; // Skip over double quote
|
||||
} else {
|
||||
valueStart = i;
|
||||
// Parse unquoted value
|
||||
for (; i < str.length; ++i) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (TOKEN[code] !== 1) {
|
||||
// No value (malformed)
|
||||
if (i === valueStart)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = str.slice(valueStart, i);
|
||||
}
|
||||
|
||||
value = defDecoder(value, 2);
|
||||
if (value === undefined)
|
||||
return;
|
||||
}
|
||||
|
||||
name = name.toLowerCase();
|
||||
if (params[name] === undefined)
|
||||
params[name] = value;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
function getDecoder(charset) {
|
||||
let lc;
|
||||
while (true) {
|
||||
switch (charset) {
|
||||
case 'utf-8':
|
||||
case 'utf8':
|
||||
return decoders.utf8;
|
||||
case 'latin1':
|
||||
case 'ascii': // TODO: Make these a separate, strict decoder?
|
||||
case 'us-ascii':
|
||||
case 'iso-8859-1':
|
||||
case 'iso8859-1':
|
||||
case 'iso88591':
|
||||
case 'iso_8859-1':
|
||||
case 'windows-1252':
|
||||
case 'iso_8859-1:1987':
|
||||
case 'cp1252':
|
||||
case 'x-cp1252':
|
||||
return decoders.latin1;
|
||||
case 'utf16le':
|
||||
case 'utf-16le':
|
||||
case 'ucs2':
|
||||
case 'ucs-2':
|
||||
return decoders.utf16le;
|
||||
case 'base64':
|
||||
return decoders.base64;
|
||||
default:
|
||||
if (lc === undefined) {
|
||||
lc = true;
|
||||
charset = charset.toLowerCase();
|
||||
continue;
|
||||
}
|
||||
return decoders.other.bind(charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const decoders = {
|
||||
utf8: (data, hint) => {
|
||||
if (data.length === 0)
|
||||
return '';
|
||||
if (typeof data === 'string') {
|
||||
// If `data` never had any percent-encoded bytes or never had any that
|
||||
// were outside of the ASCII range, then we can safely just return the
|
||||
// input since UTF-8 is ASCII compatible
|
||||
if (hint < 2)
|
||||
return data;
|
||||
|
||||
data = Buffer.from(data, 'latin1');
|
||||
}
|
||||
return data.utf8Slice(0, data.length);
|
||||
},
|
||||
|
||||
latin1: (data, hint) => {
|
||||
if (data.length === 0)
|
||||
return '';
|
||||
if (typeof data === 'string')
|
||||
return data;
|
||||
return data.latin1Slice(0, data.length);
|
||||
},
|
||||
|
||||
utf16le: (data, hint) => {
|
||||
if (data.length === 0)
|
||||
return '';
|
||||
if (typeof data === 'string')
|
||||
data = Buffer.from(data, 'latin1');
|
||||
return data.ucs2Slice(0, data.length);
|
||||
},
|
||||
|
||||
base64: (data, hint) => {
|
||||
if (data.length === 0)
|
||||
return '';
|
||||
if (typeof data === 'string')
|
||||
data = Buffer.from(data, 'latin1');
|
||||
return data.base64Slice(0, data.length);
|
||||
},
|
||||
|
||||
other: (data, hint) => {
|
||||
if (data.length === 0)
|
||||
return '';
|
||||
if (typeof data === 'string')
|
||||
data = Buffer.from(data, 'latin1');
|
||||
try {
|
||||
const decoder = new TextDecoder(this);
|
||||
return decoder.decode(data);
|
||||
} catch {}
|
||||
},
|
||||
};
|
||||
|
||||
function convertToUTF8(data, charset, hint) {
|
||||
const decode = getDecoder(charset);
|
||||
if (decode)
|
||||
return decode(data, hint);
|
||||
}
|
||||
|
||||
function basename(path) {
|
||||
if (typeof path !== 'string')
|
||||
return '';
|
||||
for (let i = path.length - 1; i >= 0; --i) {
|
||||
switch (path.charCodeAt(i)) {
|
||||
case 0x2F: // '/'
|
||||
case 0x5C: // '\'
|
||||
path = path.slice(i + 1);
|
||||
return (path === '..' || path === '.' ? '' : path);
|
||||
}
|
||||
}
|
||||
return (path === '..' || path === '.' ? '' : path);
|
||||
}
|
||||
|
||||
const TOKEN = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
const QDTEXT = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
];
|
||||
|
||||
const CHARSET = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
const EXTENDED_VALUE = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
/* eslint-disable no-multi-spaces */
|
||||
const HEX_VALUES = [
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
];
|
||||
/* eslint-enable no-multi-spaces */
|
||||
|
||||
module.exports = {
|
||||
basename,
|
||||
convertToUTF8,
|
||||
getDecoder,
|
||||
parseContentType,
|
||||
parseDisposition,
|
||||
};
|
22
node_modules/busboy/package.json
generated
vendored
Normal file
22
node_modules/busboy/package.json
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
{ "name": "busboy",
|
||||
"version": "1.6.0",
|
||||
"author": "Brian White <mscdex@mscdex.net>",
|
||||
"description": "A streaming parser for HTML form data for node.js",
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
"streamsearch": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mscdex/eslint-config": "^1.1.0",
|
||||
"eslint": "^7.32.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/test.js",
|
||||
"lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js lib test bench",
|
||||
"lint:fix": "npm run lint -- --fix"
|
||||
},
|
||||
"engines": { "node": ">=10.16.0" },
|
||||
"keywords": [ "uploads", "forms", "multipart", "form-data" ],
|
||||
"licenses": [ { "type": "MIT", "url": "http://github.com/mscdex/busboy/raw/master/LICENSE" } ],
|
||||
"repository": { "type": "git", "url": "http://github.com/mscdex/busboy.git" }
|
||||
}
|
109
node_modules/busboy/test/common.js
generated
vendored
Normal file
109
node_modules/busboy/test/common.js
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const mustCallChecks = [];
|
||||
|
||||
function noop() {}
|
||||
|
||||
function runCallChecks(exitCode) {
|
||||
if (exitCode !== 0) return;
|
||||
|
||||
const failed = mustCallChecks.filter((context) => {
|
||||
if ('minimum' in context) {
|
||||
context.messageSegment = `at least ${context.minimum}`;
|
||||
return context.actual < context.minimum;
|
||||
}
|
||||
context.messageSegment = `exactly ${context.exact}`;
|
||||
return context.actual !== context.exact;
|
||||
});
|
||||
|
||||
failed.forEach((context) => {
|
||||
console.error('Mismatched %s function calls. Expected %s, actual %d.',
|
||||
context.name,
|
||||
context.messageSegment,
|
||||
context.actual);
|
||||
console.error(context.stack.split('\n').slice(2).join('\n'));
|
||||
});
|
||||
|
||||
if (failed.length)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function mustCall(fn, exact) {
|
||||
return _mustCallInner(fn, exact, 'exact');
|
||||
}
|
||||
|
||||
function mustCallAtLeast(fn, minimum) {
|
||||
return _mustCallInner(fn, minimum, 'minimum');
|
||||
}
|
||||
|
||||
function _mustCallInner(fn, criteria = 1, field) {
|
||||
if (process._exiting)
|
||||
throw new Error('Cannot use common.mustCall*() in process exit handler');
|
||||
|
||||
if (typeof fn === 'number') {
|
||||
criteria = fn;
|
||||
fn = noop;
|
||||
} else if (fn === undefined) {
|
||||
fn = noop;
|
||||
}
|
||||
|
||||
if (typeof criteria !== 'number')
|
||||
throw new TypeError(`Invalid ${field} value: ${criteria}`);
|
||||
|
||||
const context = {
|
||||
[field]: criteria,
|
||||
actual: 0,
|
||||
stack: inspect(new Error()),
|
||||
name: fn.name || '<anonymous>'
|
||||
};
|
||||
|
||||
// Add the exit listener only once to avoid listener leak warnings
|
||||
if (mustCallChecks.length === 0)
|
||||
process.on('exit', runCallChecks);
|
||||
|
||||
mustCallChecks.push(context);
|
||||
|
||||
function wrapped(...args) {
|
||||
++context.actual;
|
||||
return fn.call(this, ...args);
|
||||
}
|
||||
// TODO: remove origFn?
|
||||
wrapped.origFn = fn;
|
||||
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
function getCallSite(top) {
|
||||
const originalStackFormatter = Error.prepareStackTrace;
|
||||
Error.prepareStackTrace = (err, stack) =>
|
||||
`${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
|
||||
const err = new Error();
|
||||
Error.captureStackTrace(err, top);
|
||||
// With the V8 Error API, the stack is not formatted until it is accessed
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
err.stack;
|
||||
Error.prepareStackTrace = originalStackFormatter;
|
||||
return err.stack;
|
||||
}
|
||||
|
||||
function mustNotCall(msg) {
|
||||
const callSite = getCallSite(mustNotCall);
|
||||
return function mustNotCall(...args) {
|
||||
args = args.map(inspect).join(', ');
|
||||
const argsInfo = (args.length > 0
|
||||
? `\ncalled with arguments: ${args}`
|
||||
: '');
|
||||
assert.fail(
|
||||
`${msg || 'function should not have been called'} at ${callSite}`
|
||||
+ argsInfo);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
mustCall,
|
||||
mustCallAtLeast,
|
||||
mustNotCall,
|
||||
};
|
94
node_modules/busboy/test/test-types-multipart-charsets.js
generated
vendored
Normal file
94
node_modules/busboy/test/test-types-multipart-charsets.js
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const { mustCall } = require(`${__dirname}/common.js`);
|
||||
|
||||
const busboy = require('..');
|
||||
|
||||
const input = Buffer.from([
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||
'Content-Disposition: form-data; '
|
||||
+ 'name="upload_file_0"; filename="テスト.dat"',
|
||||
'Content-Type: application/octet-stream',
|
||||
'',
|
||||
'A'.repeat(1023),
|
||||
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||
].join('\r\n'));
|
||||
const boundary = '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k';
|
||||
const expected = [
|
||||
{ type: 'file',
|
||||
name: 'upload_file_0',
|
||||
data: Buffer.from('A'.repeat(1023)),
|
||||
info: {
|
||||
filename: 'テスト.dat',
|
||||
encoding: '7bit',
|
||||
mimeType: 'application/octet-stream',
|
||||
},
|
||||
limited: false,
|
||||
},
|
||||
];
|
||||
const bb = busboy({
|
||||
defParamCharset: 'utf8',
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${boundary}`,
|
||||
}
|
||||
});
|
||||
const results = [];
|
||||
|
||||
bb.on('field', (name, val, info) => {
|
||||
results.push({ type: 'field', name, val, info });
|
||||
});
|
||||
|
||||
bb.on('file', (name, stream, info) => {
|
||||
const data = [];
|
||||
let nb = 0;
|
||||
const file = {
|
||||
type: 'file',
|
||||
name,
|
||||
data: null,
|
||||
info,
|
||||
limited: false,
|
||||
};
|
||||
results.push(file);
|
||||
stream.on('data', (d) => {
|
||||
data.push(d);
|
||||
nb += d.length;
|
||||
}).on('limit', () => {
|
||||
file.limited = true;
|
||||
}).on('close', () => {
|
||||
file.data = Buffer.concat(data, nb);
|
||||
assert.strictEqual(stream.truncated, file.limited);
|
||||
}).once('error', (err) => {
|
||||
file.err = err.message;
|
||||
});
|
||||
});
|
||||
|
||||
bb.on('error', (err) => {
|
||||
results.push({ error: err.message });
|
||||
});
|
||||
|
||||
bb.on('partsLimit', () => {
|
||||
results.push('partsLimit');
|
||||
});
|
||||
|
||||
bb.on('filesLimit', () => {
|
||||
results.push('filesLimit');
|
||||
});
|
||||
|
||||
bb.on('fieldsLimit', () => {
|
||||
results.push('fieldsLimit');
|
||||
});
|
||||
|
||||
bb.on('close', mustCall(() => {
|
||||
assert.deepStrictEqual(
|
||||
results,
|
||||
expected,
|
||||
'Results mismatch.\n'
|
||||
+ `Parsed: ${inspect(results)}\n`
|
||||
+ `Expected: ${inspect(expected)}`
|
||||
);
|
||||
}));
|
||||
|
||||
bb.end(input);
|
102
node_modules/busboy/test/test-types-multipart-stream-pause.js
generated
vendored
Normal file
102
node_modules/busboy/test/test-types-multipart-stream-pause.js
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { randomFillSync } = require('crypto');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const busboy = require('..');
|
||||
|
||||
const { mustCall } = require('./common.js');
|
||||
|
||||
const BOUNDARY = 'u2KxIV5yF1y+xUspOQCCZopaVgeV6Jxihv35XQJmuTx8X3sh';
|
||||
|
||||
function formDataSection(key, value) {
|
||||
return Buffer.from(
|
||||
`\r\n--${BOUNDARY}`
|
||||
+ `\r\nContent-Disposition: form-data; name="${key}"`
|
||||
+ `\r\n\r\n${value}`
|
||||
);
|
||||
}
|
||||
|
||||
function formDataFile(key, filename, contentType) {
|
||||
const buf = Buffer.allocUnsafe(100000);
|
||||
return Buffer.concat([
|
||||
Buffer.from(`\r\n--${BOUNDARY}\r\n`),
|
||||
Buffer.from(`Content-Disposition: form-data; name="${key}"`
|
||||
+ `; filename="${filename}"\r\n`),
|
||||
Buffer.from(`Content-Type: ${contentType}\r\n\r\n`),
|
||||
randomFillSync(buf)
|
||||
]);
|
||||
}
|
||||
|
||||
const reqChunks = [
|
||||
Buffer.concat([
|
||||
formDataFile('file', 'file.bin', 'application/octet-stream'),
|
||||
formDataSection('foo', 'foo value'),
|
||||
]),
|
||||
formDataSection('bar', 'bar value'),
|
||||
Buffer.from(`\r\n--${BOUNDARY}--\r\n`)
|
||||
];
|
||||
const bb = busboy({
|
||||
headers: {
|
||||
'content-type': `multipart/form-data; boundary=${BOUNDARY}`
|
||||
}
|
||||
});
|
||||
const expected = [
|
||||
{ type: 'file',
|
||||
name: 'file',
|
||||
info: {
|
||||
filename: 'file.bin',
|
||||
encoding: '7bit',
|
||||
mimeType: 'application/octet-stream',
|
||||
},
|
||||
},
|
||||
{ type: 'field',
|
||||
name: 'foo',
|
||||
val: 'foo value',
|
||||
info: {
|
||||
nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: '7bit',
|
||||
mimeType: 'text/plain',
|
||||
},
|
||||
},
|
||||
{ type: 'field',
|
||||
name: 'bar',
|
||||
val: 'bar value',
|
||||
info: {
|
||||
nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: '7bit',
|
||||
mimeType: 'text/plain',
|
||||
},
|
||||
},
|
||||
];
|
||||
const results = [];
|
||||
|
||||
bb.on('field', (name, val, info) => {
|
||||
results.push({ type: 'field', name, val, info });
|
||||
});
|
||||
|
||||
bb.on('file', (name, stream, info) => {
|
||||
results.push({ type: 'file', name, info });
|
||||
// Simulate a pipe where the destination is pausing (perhaps due to waiting
|
||||
// for file system write to finish)
|
||||
setTimeout(() => {
|
||||
stream.resume();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
bb.on('close', mustCall(() => {
|
||||
assert.deepStrictEqual(
|
||||
results,
|
||||
expected,
|
||||
'Results mismatch.\n'
|
||||
+ `Parsed: ${inspect(results)}\n`
|
||||
+ `Expected: ${inspect(expected)}`
|
||||
);
|
||||
}));
|
||||
|
||||
for (const chunk of reqChunks)
|
||||
bb.write(chunk);
|
||||
bb.end();
|
1053
node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
1053
node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
488
node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
488
node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
|
@ -0,0 +1,488 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { transcode } = require('buffer');
|
||||
const { inspect } = require('util');
|
||||
|
||||
const busboy = require('..');
|
||||
|
||||
const active = new Map();
|
||||
|
||||
const tests = [
|
||||
{ source: ['foo'],
|
||||
expected: [
|
||||
['foo',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Unassigned value'
|
||||
},
|
||||
{ source: ['foo=bar'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned value'
|
||||
},
|
||||
{ source: ['foo&bar=baz'],
|
||||
expected: [
|
||||
['foo',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['bar',
|
||||
'baz',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Unassigned and assigned value'
|
||||
},
|
||||
{ source: ['foo=bar&baz'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['baz',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned and unassigned value'
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['baz',
|
||||
'bla',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Two assigned values'
|
||||
},
|
||||
{ source: ['foo&bar'],
|
||||
expected: [
|
||||
['foo',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['bar',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Two unassigned values'
|
||||
},
|
||||
{ source: ['foo&bar&'],
|
||||
expected: [
|
||||
['foo',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['bar',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Two unassigned values and ampersand'
|
||||
},
|
||||
{ source: ['foo+1=bar+baz%2Bquux'],
|
||||
expected: [
|
||||
['foo 1',
|
||||
'bar baz+quux',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned key and value with (plus) space'
|
||||
},
|
||||
{ source: ['foo=bar%20baz%21'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar baz!',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned value with encoded bytes'
|
||||
},
|
||||
{ source: ['foo%20bar=baz%20bla%21'],
|
||||
expected: [
|
||||
['foo bar',
|
||||
'baz bla!',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned value with encoded bytes #2'
|
||||
},
|
||||
{ source: ['foo=bar%20baz%21&num=1000'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar baz!',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['num',
|
||||
'1000',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Two assigned values, one with encoded bytes'
|
||||
},
|
||||
{ source: [
|
||||
Array.from(transcode(Buffer.from('foo'), 'utf8', 'utf16le')).map(
|
||||
(n) => `%${n.toString(16).padStart(2, '0')}`
|
||||
).join(''),
|
||||
'=',
|
||||
Array.from(transcode(Buffer.from('😀!'), 'utf8', 'utf16le')).map(
|
||||
(n) => `%${n.toString(16).padStart(2, '0')}`
|
||||
).join(''),
|
||||
],
|
||||
expected: [
|
||||
['foo',
|
||||
'😀!',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'UTF-16LE',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
charset: 'UTF-16LE',
|
||||
what: 'Encoded value with multi-byte charset'
|
||||
},
|
||||
{ source: [
|
||||
'foo=<',
|
||||
Array.from(transcode(Buffer.from('©:^þ'), 'utf8', 'latin1')).map(
|
||||
(n) => `%${n.toString(16).padStart(2, '0')}`
|
||||
).join(''),
|
||||
],
|
||||
expected: [
|
||||
['foo',
|
||||
'<©:^þ',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'ISO-8859-1',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
charset: 'ISO-8859-1',
|
||||
what: 'Encoded value with single-byte, ASCII-compatible, non-UTF8 charset'
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [],
|
||||
what: 'Limits: zero fields',
|
||||
limits: { fields: 0 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: one field',
|
||||
limits: { fields: 1 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['foo',
|
||||
'bar',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['baz',
|
||||
'bla',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: field part lengths match limits',
|
||||
limits: { fieldNameSize: 3, fieldSize: 3 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['fo',
|
||||
'bar',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['ba',
|
||||
'bla',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: truncated field name',
|
||||
limits: { fieldNameSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['foo',
|
||||
'ba',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['baz',
|
||||
'bl',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: truncated field value',
|
||||
limits: { fieldSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['fo',
|
||||
'ba',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['ba',
|
||||
'bl',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: truncated field name and value',
|
||||
limits: { fieldNameSize: 2, fieldSize: 2 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['fo',
|
||||
'',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['ba',
|
||||
'',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: truncated field name and zero value limit',
|
||||
limits: { fieldNameSize: 2, fieldSize: 0 }
|
||||
},
|
||||
{ source: ['foo=bar&baz=bla'],
|
||||
expected: [
|
||||
['',
|
||||
'',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
['',
|
||||
'',
|
||||
{ nameTruncated: true,
|
||||
valueTruncated: true,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Limits: truncated zero field name and zero value limit',
|
||||
limits: { fieldNameSize: 0, fieldSize: 0 }
|
||||
},
|
||||
{ source: ['&'],
|
||||
expected: [],
|
||||
what: 'Ampersand'
|
||||
},
|
||||
{ source: ['&&&&&'],
|
||||
expected: [],
|
||||
what: 'Many ampersands'
|
||||
},
|
||||
{ source: ['='],
|
||||
expected: [
|
||||
['',
|
||||
'',
|
||||
{ nameTruncated: false,
|
||||
valueTruncated: false,
|
||||
encoding: 'utf-8',
|
||||
mimeType: 'text/plain' },
|
||||
],
|
||||
],
|
||||
what: 'Assigned value, empty name and value'
|
||||
},
|
||||
{ source: [''],
|
||||
expected: [],
|
||||
what: 'Nothing'
|
||||
},
|
||||
];
|
||||
|
||||
for (const test of tests) {
|
||||
active.set(test, 1);
|
||||
|
||||
const { what } = test;
|
||||
const charset = test.charset || 'utf-8';
|
||||
const bb = busboy({
|
||||
limits: test.limits,
|
||||
headers: {
|
||||
'content-type': `application/x-www-form-urlencoded; charset=${charset}`,
|
||||
},
|
||||
});
|
||||
const results = [];
|
||||
|
||||
bb.on('field', (key, val, info) => {
|
||||
results.push([key, val, info]);
|
||||
});
|
||||
|
||||
bb.on('file', () => {
|
||||
throw new Error(`[${what}] Unexpected file`);
|
||||
});
|
||||
|
||||
bb.on('close', () => {
|
||||
active.delete(test);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
results,
|
||||
test.expected,
|
||||
`[${what}] Results mismatch.\n`
|
||||
+ `Parsed: ${inspect(results)}\n`
|
||||
+ `Expected: ${inspect(test.expected)}`
|
||||
);
|
||||
});
|
||||
|
||||
for (const src of test.source) {
|
||||
const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
|
||||
bb.write(buf);
|
||||
}
|
||||
bb.end();
|
||||
}
|
||||
|
||||
// Byte-by-byte versions
|
||||
for (let test of tests) {
|
||||
test = { ...test };
|
||||
test.what += ' (byte-by-byte)';
|
||||
active.set(test, 1);
|
||||
|
||||
const { what } = test;
|
||||
const charset = test.charset || 'utf-8';
|
||||
const bb = busboy({
|
||||
limits: test.limits,
|
||||
headers: {
|
||||
'content-type': `application/x-www-form-urlencoded; charset="${charset}"`,
|
||||
},
|
||||
});
|
||||
const results = [];
|
||||
|
||||
bb.on('field', (key, val, info) => {
|
||||
results.push([key, val, info]);
|
||||
});
|
||||
|
||||
bb.on('file', () => {
|
||||
throw new Error(`[${what}] Unexpected file`);
|
||||
});
|
||||
|
||||
bb.on('close', () => {
|
||||
active.delete(test);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
results,
|
||||
test.expected,
|
||||
`[${what}] Results mismatch.\n`
|
||||
+ `Parsed: ${inspect(results)}\n`
|
||||
+ `Expected: ${inspect(test.expected)}`
|
||||
);
|
||||
});
|
||||
|
||||
for (const src of test.source) {
|
||||
const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
|
||||
for (let i = 0; i < buf.length; ++i)
|
||||
bb.write(buf.slice(i, i + 1));
|
||||
}
|
||||
bb.end();
|
||||
}
|
||||
|
||||
{
|
||||
let exception = false;
|
||||
process.once('uncaughtException', (ex) => {
|
||||
exception = true;
|
||||
throw ex;
|
||||
});
|
||||
process.on('exit', () => {
|
||||
if (exception || active.size === 0)
|
||||
return;
|
||||
process.exitCode = 1;
|
||||
console.error('==========================');
|
||||
console.error(`${active.size} test(s) did not finish:`);
|
||||
console.error('==========================');
|
||||
console.error(Array.from(active.keys()).map((v) => v.what).join('\n'));
|
||||
});
|
||||
}
|
20
node_modules/busboy/test/test.js
generated
vendored
Normal file
20
node_modules/busboy/test/test.js
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
const { spawnSync } = require('child_process');
|
||||
const { readdirSync } = require('fs');
|
||||
const { join } = require('path');
|
||||
|
||||
const files = readdirSync(__dirname).sort();
|
||||
for (const filename of files) {
|
||||
if (filename.startsWith('test-')) {
|
||||
const path = join(__dirname, filename);
|
||||
console.log(`> Running ${filename} ...`);
|
||||
const result = spawnSync(`${process.argv0} ${path}`, {
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
windowsHide: true
|
||||
});
|
||||
if (result.status !== 0)
|
||||
process.exitCode = 1;
|
||||
}
|
||||
}
|
24
node_modules/concat-stream/LICENSE
generated
vendored
Normal file
24
node_modules/concat-stream/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2013 Max Ogden
|
||||
|
||||
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.
|
144
node_modules/concat-stream/index.js
generated
vendored
Normal file
144
node_modules/concat-stream/index.js
generated
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
var Writable = require('readable-stream').Writable
|
||||
var inherits = require('inherits')
|
||||
var bufferFrom = require('buffer-from')
|
||||
|
||||
if (typeof Uint8Array === 'undefined') {
|
||||
var U8 = require('typedarray').Uint8Array
|
||||
} else {
|
||||
var U8 = Uint8Array
|
||||
}
|
||||
|
||||
function ConcatStream(opts, cb) {
|
||||
if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb)
|
||||
|
||||
if (typeof opts === 'function') {
|
||||
cb = opts
|
||||
opts = {}
|
||||
}
|
||||
if (!opts) opts = {}
|
||||
|
||||
var encoding = opts.encoding
|
||||
var shouldInferEncoding = false
|
||||
|
||||
if (!encoding) {
|
||||
shouldInferEncoding = true
|
||||
} else {
|
||||
encoding = String(encoding).toLowerCase()
|
||||
if (encoding === 'u8' || encoding === 'uint8') {
|
||||
encoding = 'uint8array'
|
||||
}
|
||||
}
|
||||
|
||||
Writable.call(this, { objectMode: true })
|
||||
|
||||
this.encoding = encoding
|
||||
this.shouldInferEncoding = shouldInferEncoding
|
||||
|
||||
if (cb) this.on('finish', function () { cb(this.getBody()) })
|
||||
this.body = []
|
||||
}
|
||||
|
||||
module.exports = ConcatStream
|
||||
inherits(ConcatStream, Writable)
|
||||
|
||||
ConcatStream.prototype._write = function(chunk, enc, next) {
|
||||
this.body.push(chunk)
|
||||
next()
|
||||
}
|
||||
|
||||
ConcatStream.prototype.inferEncoding = function (buff) {
|
||||
var firstBuffer = buff === undefined ? this.body[0] : buff;
|
||||
if (Buffer.isBuffer(firstBuffer)) return 'buffer'
|
||||
if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array'
|
||||
if (Array.isArray(firstBuffer)) return 'array'
|
||||
if (typeof firstBuffer === 'string') return 'string'
|
||||
if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object'
|
||||
return 'buffer'
|
||||
}
|
||||
|
||||
ConcatStream.prototype.getBody = function () {
|
||||
if (!this.encoding && this.body.length === 0) return []
|
||||
if (this.shouldInferEncoding) this.encoding = this.inferEncoding()
|
||||
if (this.encoding === 'array') return arrayConcat(this.body)
|
||||
if (this.encoding === 'string') return stringConcat(this.body)
|
||||
if (this.encoding === 'buffer') return bufferConcat(this.body)
|
||||
if (this.encoding === 'uint8array') return u8Concat(this.body)
|
||||
return this.body
|
||||
}
|
||||
|
||||
var isArray = Array.isArray || function (arr) {
|
||||
return Object.prototype.toString.call(arr) == '[object Array]'
|
||||
}
|
||||
|
||||
function isArrayish (arr) {
|
||||
return /Array\]$/.test(Object.prototype.toString.call(arr))
|
||||
}
|
||||
|
||||
function isBufferish (p) {
|
||||
return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function')
|
||||
}
|
||||
|
||||
function stringConcat (parts) {
|
||||
var strings = []
|
||||
var needsToString = false
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var p = parts[i]
|
||||
if (typeof p === 'string') {
|
||||
strings.push(p)
|
||||
} else if (Buffer.isBuffer(p)) {
|
||||
strings.push(p)
|
||||
} else if (isBufferish(p)) {
|
||||
strings.push(bufferFrom(p))
|
||||
} else {
|
||||
strings.push(bufferFrom(String(p)))
|
||||
}
|
||||
}
|
||||
if (Buffer.isBuffer(parts[0])) {
|
||||
strings = Buffer.concat(strings)
|
||||
strings = strings.toString('utf8')
|
||||
} else {
|
||||
strings = strings.join('')
|
||||
}
|
||||
return strings
|
||||
}
|
||||
|
||||
function bufferConcat (parts) {
|
||||
var bufs = []
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var p = parts[i]
|
||||
if (Buffer.isBuffer(p)) {
|
||||
bufs.push(p)
|
||||
} else if (isBufferish(p)) {
|
||||
bufs.push(bufferFrom(p))
|
||||
} else {
|
||||
bufs.push(bufferFrom(String(p)))
|
||||
}
|
||||
}
|
||||
return Buffer.concat(bufs)
|
||||
}
|
||||
|
||||
function arrayConcat (parts) {
|
||||
var res = []
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
res.push.apply(res, parts[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function u8Concat (parts) {
|
||||
var len = 0
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
if (typeof parts[i] === 'string') {
|
||||
parts[i] = bufferFrom(parts[i])
|
||||
}
|
||||
len += parts[i].length
|
||||
}
|
||||
var u8 = new U8(len)
|
||||
for (var i = 0, offset = 0; i < parts.length; i++) {
|
||||
var part = parts[i]
|
||||
for (var j = 0; j < part.length; j++) {
|
||||
u8[offset++] = part[j]
|
||||
}
|
||||
}
|
||||
return u8
|
||||
}
|
55
node_modules/concat-stream/package.json
generated
vendored
Normal file
55
node_modules/concat-stream/package.json
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"name": "concat-stream",
|
||||
"version": "1.6.2",
|
||||
"description": "writable stream that concatenates strings or binary data and calls a callback with the result",
|
||||
"tags": [
|
||||
"stream",
|
||||
"simple",
|
||||
"util",
|
||||
"utility"
|
||||
],
|
||||
"author": "Max Ogden <max@maxogden.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/maxogden/concat-stream.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://github.com/maxogden/concat-stream/issues"
|
||||
},
|
||||
"engines": [
|
||||
"node >= 0.8"
|
||||
],
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "tape test/*.js test/server/*.js"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tape": "^4.6.3"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/17..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/22..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
}
|
||||
}
|
102
node_modules/concat-stream/readme.md
generated
vendored
Normal file
102
node_modules/concat-stream/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
# concat-stream
|
||||
|
||||
Writable stream that concatenates all the data from a stream and calls a callback with the result. Use this when you want to collect all the data from a stream into a single buffer.
|
||||
|
||||
[![Build Status](https://travis-ci.org/maxogden/concat-stream.svg?branch=master)](https://travis-ci.org/maxogden/concat-stream)
|
||||
|
||||
[![NPM](https://nodei.co/npm/concat-stream.png)](https://nodei.co/npm/concat-stream/)
|
||||
|
||||
### description
|
||||
|
||||
Streams emit many buffers. If you want to collect all of the buffers, and when the stream ends concatenate all of the buffers together and receive a single buffer then this is the module for you.
|
||||
|
||||
Only use this if you know you can fit all of the output of your stream into a single Buffer (e.g. in RAM).
|
||||
|
||||
There are also `objectMode` streams that emit things other than Buffers, and you can concatenate these too. See below for details.
|
||||
|
||||
## Related
|
||||
|
||||
`concat-stream` is part of the [mississippi stream utility collection](https://github.com/maxogden/mississippi) which includes more useful stream modules similar to this one.
|
||||
|
||||
### examples
|
||||
|
||||
#### Buffers
|
||||
|
||||
```js
|
||||
var fs = require('fs')
|
||||
var concat = require('concat-stream')
|
||||
|
||||
var readStream = fs.createReadStream('cat.png')
|
||||
var concatStream = concat(gotPicture)
|
||||
|
||||
readStream.on('error', handleError)
|
||||
readStream.pipe(concatStream)
|
||||
|
||||
function gotPicture(imageBuffer) {
|
||||
// imageBuffer is all of `cat.png` as a node.js Buffer
|
||||
}
|
||||
|
||||
function handleError(err) {
|
||||
// handle your error appropriately here, e.g.:
|
||||
console.error(err) // print the error to STDERR
|
||||
process.exit(1) // exit program with non-zero exit code
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Arrays
|
||||
|
||||
```js
|
||||
var write = concat(function(data) {})
|
||||
write.write([1,2,3])
|
||||
write.write([4,5,6])
|
||||
write.end()
|
||||
// data will be [1,2,3,4,5,6] in the above callback
|
||||
```
|
||||
|
||||
#### Uint8Arrays
|
||||
|
||||
```js
|
||||
var write = concat(function(data) {})
|
||||
var a = new Uint8Array(3)
|
||||
a[0] = 97; a[1] = 98; a[2] = 99
|
||||
write.write(a)
|
||||
write.write('!')
|
||||
write.end(Buffer.from('!!1'))
|
||||
```
|
||||
|
||||
See `test/` for more examples
|
||||
|
||||
# methods
|
||||
|
||||
```js
|
||||
var concat = require('concat-stream')
|
||||
```
|
||||
|
||||
## var writable = concat(opts={}, cb)
|
||||
|
||||
Return a `writable` stream that will fire `cb(data)` with all of the data that
|
||||
was written to the stream. Data can be written to `writable` as strings,
|
||||
Buffers, arrays of byte integers, and Uint8Arrays.
|
||||
|
||||
By default `concat-stream` will give you back the same data type as the type of the first buffer written to the stream. Use `opts.encoding` to set what format `data` should be returned as, e.g. if you if you don't want to rely on the built-in type checking or for some other reason.
|
||||
|
||||
* `string` - get a string
|
||||
* `buffer` - get back a Buffer
|
||||
* `array` - get an array of byte integers
|
||||
* `uint8array`, `u8`, `uint8` - get back a Uint8Array
|
||||
* `object`, get back an array of Objects
|
||||
|
||||
If you don't specify an encoding, and the types can't be inferred (e.g. you write things that aren't in the list above), it will try to convert concat them into a `Buffer`.
|
||||
|
||||
If nothing is written to `writable` then `data` will be an empty array `[]`.
|
||||
|
||||
# error handling
|
||||
|
||||
`concat-stream` does not handle errors for you, so you must handle errors on whatever streams you pipe into `concat-stream`. This is a general rule when programming with node.js streams: always handle errors on each and every stream. Since `concat-stream` is not itself a stream it does not emit errors.
|
||||
|
||||
We recommend using [`end-of-stream`](https://npmjs.org/end-of-stream) or [`pump`](https://npmjs.org/pump) for writing error tolerant stream code.
|
||||
|
||||
# license
|
||||
|
||||
MIT LICENSE
|
19
node_modules/core-util-is/LICENSE
generated
vendored
Normal file
19
node_modules/core-util-is/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright Node.js contributors. All rights reserved.
|
||||
|
||||
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.
|
3
node_modules/core-util-is/README.md
generated
vendored
Normal file
3
node_modules/core-util-is/README.md
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# core-util-is
|
||||
|
||||
The `util.is*` functions introduced in Node v0.12.
|
107
node_modules/core-util-is/lib/util.js
generated
vendored
Normal file
107
node_modules/core-util-is/lib/util.js
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// NOTE: These type checking functions intentionally don't use `instanceof`
|
||||
// because it is fragile and can be easily faked with `Object.create()`.
|
||||
|
||||
function isArray(arg) {
|
||||
if (Array.isArray) {
|
||||
return Array.isArray(arg);
|
||||
}
|
||||
return objectToString(arg) === '[object Array]';
|
||||
}
|
||||
exports.isArray = isArray;
|
||||
|
||||
function isBoolean(arg) {
|
||||
return typeof arg === 'boolean';
|
||||
}
|
||||
exports.isBoolean = isBoolean;
|
||||
|
||||
function isNull(arg) {
|
||||
return arg === null;
|
||||
}
|
||||
exports.isNull = isNull;
|
||||
|
||||
function isNullOrUndefined(arg) {
|
||||
return arg == null;
|
||||
}
|
||||
exports.isNullOrUndefined = isNullOrUndefined;
|
||||
|
||||
function isNumber(arg) {
|
||||
return typeof arg === 'number';
|
||||
}
|
||||
exports.isNumber = isNumber;
|
||||
|
||||
function isString(arg) {
|
||||
return typeof arg === 'string';
|
||||
}
|
||||
exports.isString = isString;
|
||||
|
||||
function isSymbol(arg) {
|
||||
return typeof arg === 'symbol';
|
||||
}
|
||||
exports.isSymbol = isSymbol;
|
||||
|
||||
function isUndefined(arg) {
|
||||
return arg === void 0;
|
||||
}
|
||||
exports.isUndefined = isUndefined;
|
||||
|
||||
function isRegExp(re) {
|
||||
return objectToString(re) === '[object RegExp]';
|
||||
}
|
||||
exports.isRegExp = isRegExp;
|
||||
|
||||
function isObject(arg) {
|
||||
return typeof arg === 'object' && arg !== null;
|
||||
}
|
||||
exports.isObject = isObject;
|
||||
|
||||
function isDate(d) {
|
||||
return objectToString(d) === '[object Date]';
|
||||
}
|
||||
exports.isDate = isDate;
|
||||
|
||||
function isError(e) {
|
||||
return (objectToString(e) === '[object Error]' || e instanceof Error);
|
||||
}
|
||||
exports.isError = isError;
|
||||
|
||||
function isFunction(arg) {
|
||||
return typeof arg === 'function';
|
||||
}
|
||||
exports.isFunction = isFunction;
|
||||
|
||||
function isPrimitive(arg) {
|
||||
return arg === null ||
|
||||
typeof arg === 'boolean' ||
|
||||
typeof arg === 'number' ||
|
||||
typeof arg === 'string' ||
|
||||
typeof arg === 'symbol' || // ES6 symbol
|
||||
typeof arg === 'undefined';
|
||||
}
|
||||
exports.isPrimitive = isPrimitive;
|
||||
|
||||
exports.isBuffer = require('buffer').Buffer.isBuffer;
|
||||
|
||||
function objectToString(o) {
|
||||
return Object.prototype.toString.call(o);
|
||||
}
|
38
node_modules/core-util-is/package.json
generated
vendored
Normal file
38
node_modules/core-util-is/package.json
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "core-util-is",
|
||||
"version": "1.0.3",
|
||||
"description": "The `util.is*` functions introduced in Node v0.12.",
|
||||
"main": "lib/util.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/core-util-is"
|
||||
},
|
||||
"keywords": [
|
||||
"util",
|
||||
"isBuffer",
|
||||
"isArray",
|
||||
"isNumber",
|
||||
"isString",
|
||||
"isRegExp",
|
||||
"isThis",
|
||||
"isThat",
|
||||
"polyfill"
|
||||
],
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/isaacs/core-util-is/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test.js",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^15.0.9"
|
||||
}
|
||||
}
|
1
node_modules/isarray/.npmignore
generated
vendored
Normal file
1
node_modules/isarray/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
4
node_modules/isarray/.travis.yml
generated
vendored
Normal file
4
node_modules/isarray/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
6
node_modules/isarray/Makefile
generated
vendored
Normal file
6
node_modules/isarray/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
test:
|
||||
@node_modules/.bin/tape test.js
|
||||
|
||||
.PHONY: test
|
||||
|
60
node_modules/isarray/README.md
generated
vendored
Normal file
60
node_modules/isarray/README.md
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
# isarray
|
||||
|
||||
`Array#isArray` for older browsers.
|
||||
|
||||
[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray)
|
||||
[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray)
|
||||
|
||||
[![browser support](https://ci.testling.com/juliangruber/isarray.png)
|
||||
](https://ci.testling.com/juliangruber/isarray)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var isArray = require('isarray');
|
||||
|
||||
console.log(isArray([])); // => true
|
||||
console.log(isArray({})); // => false
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
With [npm](http://npmjs.org) do
|
||||
|
||||
```bash
|
||||
$ npm install isarray
|
||||
```
|
||||
|
||||
Then bundle for the browser with
|
||||
[browserify](https://github.com/substack/browserify).
|
||||
|
||||
With [component](http://component.io) do
|
||||
|
||||
```bash
|
||||
$ component install juliangruber/isarray
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
(MIT)
|
||||
|
||||
Copyright (c) 2013 Julian Gruber <julian@juliangruber.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.
|
19
node_modules/isarray/component.json
generated
vendored
Normal file
19
node_modules/isarray/component.json
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name" : "isarray",
|
||||
"description" : "Array#isArray for older browsers",
|
||||
"version" : "0.0.1",
|
||||
"repository" : "juliangruber/isarray",
|
||||
"homepage": "https://github.com/juliangruber/isarray",
|
||||
"main" : "index.js",
|
||||
"scripts" : [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies" : {},
|
||||
"keywords": ["browser","isarray","array"],
|
||||
"author": {
|
||||
"name": "Julian Gruber",
|
||||
"email": "mail@juliangruber.com",
|
||||
"url": "http://juliangruber.com"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
5
node_modules/isarray/index.js
generated
vendored
Normal file
5
node_modules/isarray/index.js
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
var toString = {}.toString;
|
||||
|
||||
module.exports = Array.isArray || function (arr) {
|
||||
return toString.call(arr) == '[object Array]';
|
||||
};
|
45
node_modules/isarray/package.json
generated
vendored
Normal file
45
node_modules/isarray/package.json
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "isarray",
|
||||
"description": "Array#isArray for older browsers",
|
||||
"version": "1.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/isarray.git"
|
||||
},
|
||||
"homepage": "https://github.com/juliangruber/isarray",
|
||||
"main": "index.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"tape": "~2.13.4"
|
||||
},
|
||||
"keywords": [
|
||||
"browser",
|
||||
"isarray",
|
||||
"array"
|
||||
],
|
||||
"author": {
|
||||
"name": "Julian Gruber",
|
||||
"email": "mail@juliangruber.com",
|
||||
"url": "http://juliangruber.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"testling": {
|
||||
"files": "test.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/17..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/22..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test.js"
|
||||
}
|
||||
}
|
20
node_modules/isarray/test.js
generated
vendored
Normal file
20
node_modules/isarray/test.js
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
var isArray = require('./');
|
||||
var test = require('tape');
|
||||
|
||||
test('is array', function(t){
|
||||
t.ok(isArray([]));
|
||||
t.notOk(isArray({}));
|
||||
t.notOk(isArray(null));
|
||||
t.notOk(isArray(false));
|
||||
|
||||
var obj = {};
|
||||
obj[0] = true;
|
||||
t.notOk(isArray(obj));
|
||||
|
||||
var arr = [];
|
||||
arr.foo = 'bar';
|
||||
t.ok(isArray(arr));
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
29
node_modules/minimist/.eslintrc
generated
vendored
Normal file
29
node_modules/minimist/.eslintrc
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"root": true,
|
||||
|
||||
"extends": "@ljharb/eslint-config/node/0.4",
|
||||
|
||||
"rules": {
|
||||
"array-element-newline": 0,
|
||||
"complexity": 0,
|
||||
"func-style": [2, "declaration"],
|
||||
"max-lines-per-function": 0,
|
||||
"max-nested-callbacks": 1,
|
||||
"max-statements-per-line": 1,
|
||||
"max-statements": 0,
|
||||
"multiline-comment-style": 0,
|
||||
"no-continue": 1,
|
||||
"no-param-reassign": 1,
|
||||
"no-restricted-syntax": 1,
|
||||
"object-curly-newline": 0,
|
||||
},
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": "test/**",
|
||||
"rules": {
|
||||
"camelcase": 0,
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
12
node_modules/minimist/.github/FUNDING.yml
generated
vendored
Normal file
12
node_modules/minimist/.github/FUNDING.yml
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [ljharb]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: npm/minimist
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
14
node_modules/minimist/.nycrc
generated
vendored
Normal file
14
node_modules/minimist/.nycrc
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"all": true,
|
||||
"check-coverage": false,
|
||||
"reporter": ["text-summary", "text", "html", "json"],
|
||||
"lines": 86,
|
||||
"statements": 85.93,
|
||||
"functions": 82.43,
|
||||
"branches": 76.06,
|
||||
"exclude": [
|
||||
"coverage",
|
||||
"example",
|
||||
"test"
|
||||
]
|
||||
}
|
298
node_modules/minimist/CHANGELOG.md
generated
vendored
Normal file
298
node_modules/minimist/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,298 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [v1.2.8](https://github.com/minimistjs/minimist/compare/v1.2.7...v1.2.8) - 2023-02-09
|
||||
|
||||
### Merged
|
||||
|
||||
- [Fix] Fix long option followed by single dash [`#17`](https://github.com/minimistjs/minimist/pull/17)
|
||||
- [Tests] Remove duplicate test [`#12`](https://github.com/minimistjs/minimist/pull/12)
|
||||
- [Fix] opt.string works with multiple aliases [`#10`](https://github.com/minimistjs/minimist/pull/10)
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Fix] Fix long option followed by single dash (#17) [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||
- [Tests] Remove duplicate test (#12) [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||
- [Fix] Fix long option followed by single dash [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||
- [Fix] opt.string works with multiple aliases (#10) [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||
- [Fix] Fix handling of short option with non-trivial equals [`#5`](https://github.com/minimistjs/minimist/issues/5)
|
||||
- [Tests] Remove duplicate test [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||
- [Fix] opt.string works with multiple aliases [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||
|
||||
### Commits
|
||||
|
||||
- Merge tag 'v0.2.3' [`a026794`](https://github.com/minimistjs/minimist/commit/a0267947c7870fc5847cf2d437fbe33f392767da)
|
||||
- [eslint] fix indentation and whitespace [`5368ca4`](https://github.com/minimistjs/minimist/commit/5368ca4147e974138a54cc0dc4cea8f756546b70)
|
||||
- [eslint] fix indentation and whitespace [`e5f5067`](https://github.com/minimistjs/minimist/commit/e5f5067259ceeaf0b098d14bec910f87e58708c7)
|
||||
- [eslint] more cleanup [`62fde7d`](https://github.com/minimistjs/minimist/commit/62fde7d935f83417fb046741531a9e2346a36976)
|
||||
- [eslint] more cleanup [`36ac5d0`](https://github.com/minimistjs/minimist/commit/36ac5d0d95e4947d074e5737d94814034ca335d1)
|
||||
- [meta] add `auto-changelog` [`73923d2`](https://github.com/minimistjs/minimist/commit/73923d223553fca08b1ba77e3fbc2a492862ae4c)
|
||||
- [actions] add reusable workflows [`d80727d`](https://github.com/minimistjs/minimist/commit/d80727df77bfa9e631044d7f16368d8f09242c91)
|
||||
- [eslint] add eslint; rules to enable later are warnings [`48bc06a`](https://github.com/minimistjs/minimist/commit/48bc06a1b41f00e9cdf183db34f7a51ba70e98d4)
|
||||
- [eslint] fix indentation [`34b0f1c`](https://github.com/minimistjs/minimist/commit/34b0f1ccaa45183c3c4f06a91f9b405180a6f982)
|
||||
- [readme] rename and add badges [`5df0fe4`](https://github.com/minimistjs/minimist/commit/5df0fe49211bd09a3636f8686a7cb3012c3e98f0)
|
||||
- [Dev Deps] switch from `covert` to `nyc` [`a48b128`](https://github.com/minimistjs/minimist/commit/a48b128fdb8d427dfb20a15273f83e38d97bef07)
|
||||
- [Dev Deps] update `covert`, `tape`; remove unnecessary `tap` [`f0fb958`](https://github.com/minimistjs/minimist/commit/f0fb958e9a1fe980cdffc436a211b0bda58f621b)
|
||||
- [meta] create FUNDING.yml; add `funding` in package.json [`3639e0c`](https://github.com/minimistjs/minimist/commit/3639e0c819359a366387e425ab6eabf4c78d3caa)
|
||||
- [meta] use `npmignore` to autogenerate an npmignore file [`be2e038`](https://github.com/minimistjs/minimist/commit/be2e038c342d8333b32f0fde67a0026b79c8150e)
|
||||
- Only apps should have lockfiles [`282b570`](https://github.com/minimistjs/minimist/commit/282b570e7489d01b03f2d6d3dabf79cd3e5f84cf)
|
||||
- isConstructorOrProto adapted from PR [`ef9153f`](https://github.com/minimistjs/minimist/commit/ef9153fc52b6cea0744b2239921c5dcae4697f11)
|
||||
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`098873c`](https://github.com/minimistjs/minimist/commit/098873c213cdb7c92e55ae1ef5aa1af3a8192a79)
|
||||
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`3124ed3`](https://github.com/minimistjs/minimist/commit/3124ed3e46306301ebb3c834874ce0241555c2c4)
|
||||
- [meta] add `safe-publish-latest` [`4b927de`](https://github.com/minimistjs/minimist/commit/4b927de696d561c636b4f43bf49d4597cb36d6d6)
|
||||
- [Tests] add `aud` in `posttest` [`b32d9bd`](https://github.com/minimistjs/minimist/commit/b32d9bd0ab340f4e9f8c3a97ff2a4424f25fab8c)
|
||||
- [meta] update repo URLs [`f9fdfc0`](https://github.com/minimistjs/minimist/commit/f9fdfc032c54884d9a9996a390c63cd0719bbe1a)
|
||||
- [actions] Avoid 0.6 tests due to build failures [`ba92fe6`](https://github.com/minimistjs/minimist/commit/ba92fe6ebbdc0431cca9a2ea8f27beb492f5e4ec)
|
||||
- [Dev Deps] update `tape` [`950eaa7`](https://github.com/minimistjs/minimist/commit/950eaa74f112e04d23e9c606c67472c46739b473)
|
||||
- [Dev Deps] add missing `npmignore` dev dep [`3226afa`](https://github.com/minimistjs/minimist/commit/3226afaf09e9d127ca369742437fe6e88f752d6b)
|
||||
- Merge tag 'v0.2.2' [`980d7ac`](https://github.com/minimistjs/minimist/commit/980d7ac61a0b4bd552711251ac107d506b23e41f)
|
||||
|
||||
## [v1.2.7](https://github.com/minimistjs/minimist/compare/v1.2.6...v1.2.7) - 2022-10-10
|
||||
|
||||
### Commits
|
||||
|
||||
- [meta] add `auto-changelog` [`0ebf4eb`](https://github.com/minimistjs/minimist/commit/0ebf4ebcd5f7787a5524d31a849ef41316b83c3c)
|
||||
- [actions] add reusable workflows [`e115b63`](https://github.com/minimistjs/minimist/commit/e115b63fa9d3909f33b00a2db647ff79068388de)
|
||||
- [eslint] add eslint; rules to enable later are warnings [`f58745b`](https://github.com/minimistjs/minimist/commit/f58745b9bb84348e1be72af7dbba5840c7c13013)
|
||||
- [Dev Deps] switch from `covert` to `nyc` [`ab03356`](https://github.com/minimistjs/minimist/commit/ab033567b9c8b31117cb026dc7f1e592ce455c65)
|
||||
- [readme] rename and add badges [`236f4a0`](https://github.com/minimistjs/minimist/commit/236f4a07e4ebe5ee44f1496ec6974991ab293ffd)
|
||||
- [meta] create FUNDING.yml; add `funding` in package.json [`783a49b`](https://github.com/minimistjs/minimist/commit/783a49bfd47e8335d3098a8cac75662cf71eb32a)
|
||||
- [meta] use `npmignore` to autogenerate an npmignore file [`f81ece6`](https://github.com/minimistjs/minimist/commit/f81ece6aaec2fa14e69ff4f1e0407a8c4e2635a2)
|
||||
- Only apps should have lockfiles [`56cad44`](https://github.com/minimistjs/minimist/commit/56cad44c7f879b9bb5ec18fcc349308024a89bfc)
|
||||
- [Dev Deps] update `covert`, `tape`; remove unnecessary `tap` [`49c5f9f`](https://github.com/minimistjs/minimist/commit/49c5f9fb7e6a92db9eb340cc679de92fb3aacded)
|
||||
- [Tests] add `aud` in `posttest` [`228ae93`](https://github.com/minimistjs/minimist/commit/228ae938f3cd9db9dfd8bd7458b076a7b2aef280)
|
||||
- [meta] add `safe-publish-latest` [`01fc23f`](https://github.com/minimistjs/minimist/commit/01fc23f5104f85c75059972e01dd33796ab529ff)
|
||||
- [meta] update repo URLs [`6b164c7`](https://github.com/minimistjs/minimist/commit/6b164c7d68e0b6bf32f894699effdfb7c63041dd)
|
||||
|
||||
## [v1.2.6](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.6) - 2022-03-21
|
||||
|
||||
### Commits
|
||||
|
||||
- test from prototype pollution PR [`bc8ecee`](https://github.com/minimistjs/minimist/commit/bc8ecee43875261f4f17eb20b1243d3ed15e70eb)
|
||||
- isConstructorOrProto adapted from PR [`c2b9819`](https://github.com/minimistjs/minimist/commit/c2b981977fa834b223b408cfb860f933c9811e4d)
|
||||
- security notice for additional prototype pollution issue [`ef88b93`](https://github.com/minimistjs/minimist/commit/ef88b9325f77b5ee643ccfc97e2ebda577e4c4e2)
|
||||
|
||||
## [v1.2.5](https://github.com/minimistjs/minimist/compare/v1.2.4...v1.2.5) - 2020-03-12
|
||||
|
||||
## [v1.2.4](https://github.com/minimistjs/minimist/compare/v1.2.3...v1.2.4) - 2020-03-11
|
||||
|
||||
### Commits
|
||||
|
||||
- security notice [`4cf1354`](https://github.com/minimistjs/minimist/commit/4cf1354839cb972e38496d35e12f806eea92c11f)
|
||||
- additional test for constructor prototype pollution [`1043d21`](https://github.com/minimistjs/minimist/commit/1043d212c3caaf871966e710f52cfdf02f9eea4b)
|
||||
|
||||
## [v1.2.3](https://github.com/minimistjs/minimist/compare/v1.2.2...v1.2.3) - 2020-03-10
|
||||
|
||||
### Commits
|
||||
|
||||
- more failing proto pollution tests [`13c01a5`](https://github.com/minimistjs/minimist/commit/13c01a5327736903704984b7f65616b8476850cc)
|
||||
- even more aggressive checks for protocol pollution [`38a4d1c`](https://github.com/minimistjs/minimist/commit/38a4d1caead72ef99e824bb420a2528eec03d9ab)
|
||||
|
||||
## [v1.2.2](https://github.com/minimistjs/minimist/compare/v1.2.1...v1.2.2) - 2020-03-10
|
||||
|
||||
### Commits
|
||||
|
||||
- failing test for protocol pollution [`0efed03`](https://github.com/minimistjs/minimist/commit/0efed0340ec8433638758f7ca0c77cb20a0bfbab)
|
||||
- cleanup [`67d3722`](https://github.com/minimistjs/minimist/commit/67d3722413448d00a62963d2d30c34656a92d7e2)
|
||||
- console.dir -> console.log [`47acf72`](https://github.com/minimistjs/minimist/commit/47acf72c715a630bf9ea013867f47f1dd69dfc54)
|
||||
- don't assign onto __proto__ [`63e7ed0`](https://github.com/minimistjs/minimist/commit/63e7ed05aa4b1889ec2f3b196426db4500cbda94)
|
||||
|
||||
## [v1.2.1](https://github.com/minimistjs/minimist/compare/v1.2.0...v1.2.1) - 2020-03-10
|
||||
|
||||
### Merged
|
||||
|
||||
- move the `opts['--']` example back where it belongs [`#63`](https://github.com/minimistjs/minimist/pull/63)
|
||||
|
||||
### Commits
|
||||
|
||||
- add test [`6be5dae`](https://github.com/minimistjs/minimist/commit/6be5dae35a32a987bcf4137fcd6c19c5200ee909)
|
||||
- fix bad boolean regexp [`ac3fc79`](https://github.com/minimistjs/minimist/commit/ac3fc796e63b95128fdbdf67ea7fad71bd59aa76)
|
||||
|
||||
## [v1.2.0](https://github.com/minimistjs/minimist/compare/v1.1.3...v1.2.0) - 2015-08-24
|
||||
|
||||
### Commits
|
||||
|
||||
- failing -k=v short test [`63416b8`](https://github.com/minimistjs/minimist/commit/63416b8cd1d0d70e4714564cce465a36e4dd26d7)
|
||||
- kv short fix [`6bbe145`](https://github.com/minimistjs/minimist/commit/6bbe14529166245e86424f220a2321442fe88dc3)
|
||||
- failing kv short test [`f72ab7f`](https://github.com/minimistjs/minimist/commit/f72ab7f4572adc52902c9b6873cc969192f01b10)
|
||||
- fixed kv test [`f5a48c3`](https://github.com/minimistjs/minimist/commit/f5a48c3e50e40ca54f00c8e84de4b4d6e9897fa8)
|
||||
- enforce space between arg key and value [`86b321a`](https://github.com/minimistjs/minimist/commit/86b321affe648a8e016c095a4f0efa9d9074f502)
|
||||
|
||||
## [v1.1.3](https://github.com/minimistjs/minimist/compare/v1.1.2...v1.1.3) - 2015-08-06
|
||||
|
||||
### Commits
|
||||
|
||||
- add failing test - boolean alias array [`0fa3c5b`](https://github.com/minimistjs/minimist/commit/0fa3c5b3dd98551ddecf5392831b4c21211743fc)
|
||||
- fix boolean values with multiple aliases [`9c0a6e7`](https://github.com/minimistjs/minimist/commit/9c0a6e7de25a273b11bbf9a7464f0bd833779795)
|
||||
|
||||
## [v1.1.2](https://github.com/minimistjs/minimist/compare/v1.1.1...v1.1.2) - 2015-07-22
|
||||
|
||||
### Commits
|
||||
|
||||
- Convert boolean arguments to boolean values [`8f3dc27`](https://github.com/minimistjs/minimist/commit/8f3dc27cf833f1d54671b6d0bcb55c2fe19672a9)
|
||||
- use non-ancient npm, node 0.12 and iojs [`61ed1d0`](https://github.com/minimistjs/minimist/commit/61ed1d034b9ec7282764ce76f3992b1a0b4906ae)
|
||||
- an older npm for 0.8 [`25cf778`](https://github.com/minimistjs/minimist/commit/25cf778b1220e7838a526832ad6972f75244054f)
|
||||
|
||||
## [v1.1.1](https://github.com/minimistjs/minimist/compare/v1.1.0...v1.1.1) - 2015-03-10
|
||||
|
||||
### Commits
|
||||
|
||||
- check that they type of a value is a boolean, not just that it is currently set to a boolean [`6863198`](https://github.com/minimistjs/minimist/commit/6863198e36139830ff1f20ffdceaddd93f2c1db9)
|
||||
- upgrade tape, fix type issues from old tape version [`806712d`](https://github.com/minimistjs/minimist/commit/806712df91604ed02b8e39aa372b84aea659ee34)
|
||||
- test for setting a boolean to a null default [`8c444fe`](https://github.com/minimistjs/minimist/commit/8c444fe89384ded7d441c120915ea60620b01dd3)
|
||||
- if the previous value was a boolean, without an default (or with an alias) don't make an array either [`e5f419a`](https://github.com/minimistjs/minimist/commit/e5f419a3b5b3bc3f9e5ac71b7040621af70ed2dd)
|
||||
|
||||
## [v1.1.0](https://github.com/minimistjs/minimist/compare/v1.0.0...v1.1.0) - 2014-08-10
|
||||
|
||||
### Commits
|
||||
|
||||
- add support for handling "unknown" options not registered with the parser. [`6f3cc5d`](https://github.com/minimistjs/minimist/commit/6f3cc5d4e84524932a6ef2ce3592acc67cdd4383)
|
||||
- reformat package.json [`02ed371`](https://github.com/minimistjs/minimist/commit/02ed37115194d3697ff358e8e25e5e66bab1d9f8)
|
||||
- coverage script [`e5531ba`](https://github.com/minimistjs/minimist/commit/e5531ba0479da3b8138d3d8cac545d84ccb1c8df)
|
||||
- extra fn to get 100% coverage again [`a6972da`](https://github.com/minimistjs/minimist/commit/a6972da89e56bf77642f8ec05a13b6558db93498)
|
||||
|
||||
## [v1.0.0](https://github.com/minimistjs/minimist/compare/v0.2.3...v1.0.0) - 2014-08-10
|
||||
|
||||
### Commits
|
||||
|
||||
- added stopEarly option [`471c7e4`](https://github.com/minimistjs/minimist/commit/471c7e4a7e910fc7ad8f9df850a186daf32c64e9)
|
||||
- fix list [`fef6ae7`](https://github.com/minimistjs/minimist/commit/fef6ae79c38b9dc1c49569abb7cd04eb965eac5e)
|
||||
|
||||
## [v0.2.3](https://github.com/minimistjs/minimist/compare/v0.2.2...v0.2.3) - 2023-02-09
|
||||
|
||||
### Merged
|
||||
|
||||
- [Fix] Fix long option followed by single dash [`#17`](https://github.com/minimistjs/minimist/pull/17)
|
||||
- [Tests] Remove duplicate test [`#12`](https://github.com/minimistjs/minimist/pull/12)
|
||||
- [Fix] opt.string works with multiple aliases [`#10`](https://github.com/minimistjs/minimist/pull/10)
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Fix] Fix long option followed by single dash (#17) [`#15`](https://github.com/minimistjs/minimist/issues/15)
|
||||
- [Tests] Remove duplicate test (#12) [`#8`](https://github.com/minimistjs/minimist/issues/8)
|
||||
- [Fix] opt.string works with multiple aliases (#10) [`#9`](https://github.com/minimistjs/minimist/issues/9)
|
||||
|
||||
### Commits
|
||||
|
||||
- [eslint] fix indentation and whitespace [`e5f5067`](https://github.com/minimistjs/minimist/commit/e5f5067259ceeaf0b098d14bec910f87e58708c7)
|
||||
- [eslint] more cleanup [`36ac5d0`](https://github.com/minimistjs/minimist/commit/36ac5d0d95e4947d074e5737d94814034ca335d1)
|
||||
- [eslint] fix indentation [`34b0f1c`](https://github.com/minimistjs/minimist/commit/34b0f1ccaa45183c3c4f06a91f9b405180a6f982)
|
||||
- isConstructorOrProto adapted from PR [`ef9153f`](https://github.com/minimistjs/minimist/commit/ef9153fc52b6cea0744b2239921c5dcae4697f11)
|
||||
- [Dev Deps] update `@ljharb/eslint-config`, `aud` [`098873c`](https://github.com/minimistjs/minimist/commit/098873c213cdb7c92e55ae1ef5aa1af3a8192a79)
|
||||
- [Dev Deps] add missing `npmignore` dev dep [`3226afa`](https://github.com/minimistjs/minimist/commit/3226afaf09e9d127ca369742437fe6e88f752d6b)
|
||||
|
||||
## [v0.2.2](https://github.com/minimistjs/minimist/compare/v0.2.1...v0.2.2) - 2022-10-10
|
||||
|
||||
### Commits
|
||||
|
||||
- [meta] add `auto-changelog` [`73923d2`](https://github.com/minimistjs/minimist/commit/73923d223553fca08b1ba77e3fbc2a492862ae4c)
|
||||
- [actions] add reusable workflows [`d80727d`](https://github.com/minimistjs/minimist/commit/d80727df77bfa9e631044d7f16368d8f09242c91)
|
||||
- [eslint] add eslint; rules to enable later are warnings [`48bc06a`](https://github.com/minimistjs/minimist/commit/48bc06a1b41f00e9cdf183db34f7a51ba70e98d4)
|
||||
- [readme] rename and add badges [`5df0fe4`](https://github.com/minimistjs/minimist/commit/5df0fe49211bd09a3636f8686a7cb3012c3e98f0)
|
||||
- [Dev Deps] switch from `covert` to `nyc` [`a48b128`](https://github.com/minimistjs/minimist/commit/a48b128fdb8d427dfb20a15273f83e38d97bef07)
|
||||
- [Dev Deps] update `covert`, `tape`; remove unnecessary `tap` [`f0fb958`](https://github.com/minimistjs/minimist/commit/f0fb958e9a1fe980cdffc436a211b0bda58f621b)
|
||||
- [meta] create FUNDING.yml; add `funding` in package.json [`3639e0c`](https://github.com/minimistjs/minimist/commit/3639e0c819359a366387e425ab6eabf4c78d3caa)
|
||||
- [meta] use `npmignore` to autogenerate an npmignore file [`be2e038`](https://github.com/minimistjs/minimist/commit/be2e038c342d8333b32f0fde67a0026b79c8150e)
|
||||
- Only apps should have lockfiles [`282b570`](https://github.com/minimistjs/minimist/commit/282b570e7489d01b03f2d6d3dabf79cd3e5f84cf)
|
||||
- [meta] add `safe-publish-latest` [`4b927de`](https://github.com/minimistjs/minimist/commit/4b927de696d561c636b4f43bf49d4597cb36d6d6)
|
||||
- [Tests] add `aud` in `posttest` [`b32d9bd`](https://github.com/minimistjs/minimist/commit/b32d9bd0ab340f4e9f8c3a97ff2a4424f25fab8c)
|
||||
- [meta] update repo URLs [`f9fdfc0`](https://github.com/minimistjs/minimist/commit/f9fdfc032c54884d9a9996a390c63cd0719bbe1a)
|
||||
|
||||
## [v0.2.1](https://github.com/minimistjs/minimist/compare/v0.2.0...v0.2.1) - 2020-03-12
|
||||
|
||||
## [v0.2.0](https://github.com/minimistjs/minimist/compare/v0.1.0...v0.2.0) - 2014-06-19
|
||||
|
||||
### Commits
|
||||
|
||||
- support all-boolean mode [`450a97f`](https://github.com/minimistjs/minimist/commit/450a97f6e2bc85c7a4a13185c19a818d9a5ebe69)
|
||||
|
||||
## [v0.1.0](https://github.com/minimistjs/minimist/compare/v0.0.10...v0.1.0) - 2014-05-12
|
||||
|
||||
### Commits
|
||||
|
||||
- Provide a mechanism to segregate -- arguments [`ce4a1e6`](https://github.com/minimistjs/minimist/commit/ce4a1e63a7e8d5ab88d2a3768adefa6af98a445a)
|
||||
- documented argv['--'] [`14db0e6`](https://github.com/minimistjs/minimist/commit/14db0e6dbc6d2b9e472adaa54dad7004b364634f)
|
||||
- Adding a test-case for notFlags segregation [`715c1e3`](https://github.com/minimistjs/minimist/commit/715c1e3714be223f998f6c537af6b505f0236c16)
|
||||
|
||||
## [v0.0.10](https://github.com/minimistjs/minimist/compare/v0.0.9...v0.0.10) - 2014-05-11
|
||||
|
||||
### Commits
|
||||
|
||||
- dedicated boolean test [`46e448f`](https://github.com/minimistjs/minimist/commit/46e448f9f513cfeb2bcc8b688b9b47ba1e515c2b)
|
||||
- dedicated num test [`9bf2d36`](https://github.com/minimistjs/minimist/commit/9bf2d36f1d3b8795be90b8f7de0a937f098aa394)
|
||||
- aliased values treated as strings [`1ab743b`](https://github.com/minimistjs/minimist/commit/1ab743bad4484d69f1259bed42f9531de01119de)
|
||||
- cover the case of already numbers, at 100% coverage [`b2bb044`](https://github.com/minimistjs/minimist/commit/b2bb04436599d77a2ce029e8e555e25b3aa55d13)
|
||||
- another test for higher coverage [`3662624`](https://github.com/minimistjs/minimist/commit/3662624be976d5489d486a856849c048d13be903)
|
||||
|
||||
## [v0.0.9](https://github.com/minimistjs/minimist/compare/v0.0.8...v0.0.9) - 2014-05-08
|
||||
|
||||
### Commits
|
||||
|
||||
- Eliminate `longest` fn. [`824f642`](https://github.com/minimistjs/minimist/commit/824f642038d1b02ede68b6261d1d65163390929a)
|
||||
|
||||
## [v0.0.8](https://github.com/minimistjs/minimist/compare/v0.0.7...v0.0.8) - 2014-02-20
|
||||
|
||||
### Commits
|
||||
|
||||
- return '' if flag is string and empty [`fa63ed4`](https://github.com/minimistjs/minimist/commit/fa63ed4651a4ef4eefddce34188e0d98d745a263)
|
||||
- handle joined single letters [`66c248f`](https://github.com/minimistjs/minimist/commit/66c248f0241d4d421d193b022e9e365f11178534)
|
||||
|
||||
## [v0.0.7](https://github.com/minimistjs/minimist/compare/v0.0.6...v0.0.7) - 2014-02-08
|
||||
|
||||
### Commits
|
||||
|
||||
- another swap of .test for .match [`d1da408`](https://github.com/minimistjs/minimist/commit/d1da40819acbe846d89a5c02721211e3c1260dde)
|
||||
|
||||
## [v0.0.6](https://github.com/minimistjs/minimist/compare/v0.0.5...v0.0.6) - 2014-02-08
|
||||
|
||||
### Commits
|
||||
|
||||
- use .test() instead of .match() to not crash on non-string values in the arguments array [`7e0d1ad`](https://github.com/minimistjs/minimist/commit/7e0d1add8c9e5b9b20a4d3d0f9a94d824c578da1)
|
||||
|
||||
## [v0.0.5](https://github.com/minimistjs/minimist/compare/v0.0.4...v0.0.5) - 2013-09-18
|
||||
|
||||
### Commits
|
||||
|
||||
- Improve '--' handling. [`b11822c`](https://github.com/minimistjs/minimist/commit/b11822c09cc9d2460f30384d12afc0b953c037a4)
|
||||
|
||||
## [v0.0.4](https://github.com/minimistjs/minimist/compare/v0.0.3...v0.0.4) - 2013-09-17
|
||||
|
||||
## [v0.0.3](https://github.com/minimistjs/minimist/compare/v0.0.2...v0.0.3) - 2013-09-12
|
||||
|
||||
### Commits
|
||||
|
||||
- failing test for single dash preceeding a double dash [`b465514`](https://github.com/minimistjs/minimist/commit/b465514b82c9ae28972d714facd951deb2ad762b)
|
||||
- fix for the dot test [`6a095f1`](https://github.com/minimistjs/minimist/commit/6a095f1d364c8fab2d6753d2291a0649315d297a)
|
||||
|
||||
## [v0.0.2](https://github.com/minimistjs/minimist/compare/v0.0.1...v0.0.2) - 2013-08-28
|
||||
|
||||
### Commits
|
||||
|
||||
- allow dotted aliases & defaults [`321c33e`](https://github.com/minimistjs/minimist/commit/321c33e755485faaeb44eeb1c05d33b2e0a5a7c4)
|
||||
- use a better version of ff [`e40f611`](https://github.com/minimistjs/minimist/commit/e40f61114cf7be6f7947f7b3eed345853a67dbbb)
|
||||
|
||||
## [v0.0.1](https://github.com/minimistjs/minimist/compare/v0.0.0...v0.0.1) - 2013-06-25
|
||||
|
||||
### Commits
|
||||
|
||||
- remove trailing commas [`6ff0fa0`](https://github.com/minimistjs/minimist/commit/6ff0fa055064f15dbe06d50b89d5173a6796e1db)
|
||||
|
||||
## v0.0.0 - 2013-06-25
|
||||
|
||||
### Commits
|
||||
|
||||
- half of the parse test ported [`3079326`](https://github.com/minimistjs/minimist/commit/307932601325087de6cf94188eb798ffc4f3088a)
|
||||
- stripped down code and a passing test from optimist [`7cced88`](https://github.com/minimistjs/minimist/commit/7cced88d82e399d1a03ed23eb667f04d3f320d10)
|
||||
- ported parse tests completely over [`9448754`](https://github.com/minimistjs/minimist/commit/944875452e0820df6830b1408c26a0f7d3e1db04)
|
||||
- docs, package.json [`a5bf46a`](https://github.com/minimistjs/minimist/commit/a5bf46ac9bb3bd114a9c340276c62c1091e538d5)
|
||||
- move more short tests into short.js [`503edb5`](https://github.com/minimistjs/minimist/commit/503edb5c41d89c0d40831ee517154fc13b0f18b9)
|
||||
- default bool test was wrong, not the code [`1b9f5db`](https://github.com/minimistjs/minimist/commit/1b9f5db4741b49962846081b68518de824992097)
|
||||
- passing long tests ripped out of parse.js [`7972c4a`](https://github.com/minimistjs/minimist/commit/7972c4aff1f4803079e1668006658e2a761a0428)
|
||||
- badges [`84c0370`](https://github.com/minimistjs/minimist/commit/84c037063664d42878aace715fe6572ce01b6f3b)
|
||||
- all the tests now ported, some failures [`64239ed`](https://github.com/minimistjs/minimist/commit/64239edfe92c711c4eb0da254fcdfad2a5fdb605)
|
||||
- failing short test [`f8a5341`](https://github.com/minimistjs/minimist/commit/f8a534112dd1138d2fad722def56a848480c446f)
|
||||
- fixed the numeric test [`6b034f3`](https://github.com/minimistjs/minimist/commit/6b034f37c79342c60083ed97fd222e16928aac51)
|
18
node_modules/minimist/LICENSE
generated
vendored
Normal file
18
node_modules/minimist/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
This software is released under the MIT license:
|
||||
|
||||
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.
|
121
node_modules/minimist/README.md
generated
vendored
Normal file
121
node_modules/minimist/README.md
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
# minimist <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
|
||||
|
||||
[![github actions][actions-image]][actions-url]
|
||||
[![coverage][codecov-image]][codecov-url]
|
||||
[![License][license-image]][license-url]
|
||||
[![Downloads][downloads-image]][downloads-url]
|
||||
|
||||
[![npm badge][npm-badge-png]][package-url]
|
||||
|
||||
parse argument options
|
||||
|
||||
This module is the guts of optimist's argument parser without all the
|
||||
fanciful decoration.
|
||||
|
||||
# example
|
||||
|
||||
``` js
|
||||
var argv = require('minimist')(process.argv.slice(2));
|
||||
console.log(argv);
|
||||
```
|
||||
|
||||
```
|
||||
$ node example/parse.js -a beep -b boop
|
||||
{ _: [], a: 'beep', b: 'boop' }
|
||||
```
|
||||
|
||||
```
|
||||
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
|
||||
{
|
||||
_: ['foo', 'bar', 'baz'],
|
||||
x: 3,
|
||||
y: 4,
|
||||
n: 5,
|
||||
a: true,
|
||||
b: true,
|
||||
c: true,
|
||||
beep: 'boop'
|
||||
}
|
||||
```
|
||||
|
||||
# security
|
||||
|
||||
Previous versions had a prototype pollution bug that could cause privilege
|
||||
escalation in some circumstances when handling untrusted user input.
|
||||
|
||||
Please use version 1.2.6 or later:
|
||||
|
||||
* https://security.snyk.io/vuln/SNYK-JS-MINIMIST-2429795 (version <=1.2.5)
|
||||
* https://snyk.io/vuln/SNYK-JS-MINIMIST-559764 (version <=1.2.3)
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var parseArgs = require('minimist')
|
||||
```
|
||||
|
||||
## var argv = parseArgs(args, opts={})
|
||||
|
||||
Return an argument object `argv` populated with the array arguments from `args`.
|
||||
|
||||
`argv._` contains all the arguments that didn't have an option associated with
|
||||
them.
|
||||
|
||||
Numeric-looking arguments will be returned as numbers unless `opts.string` or
|
||||
`opts.boolean` is set for that argument name.
|
||||
|
||||
Any arguments after `'--'` will not be parsed and will end up in `argv._`.
|
||||
|
||||
options can be:
|
||||
|
||||
* `opts.string` - a string or array of strings argument names to always treat as
|
||||
strings
|
||||
* `opts.boolean` - a boolean, string or array of strings to always treat as
|
||||
booleans. if `true` will treat all double hyphenated arguments without equal signs
|
||||
as boolean (e.g. affects `--foo`, not `-f` or `--foo=bar`)
|
||||
* `opts.alias` - an object mapping string names to strings or arrays of string
|
||||
argument names to use as aliases
|
||||
* `opts.default` - an object mapping string argument names to default values
|
||||
* `opts.stopEarly` - when true, populate `argv._` with everything after the
|
||||
first non-option
|
||||
* `opts['--']` - when true, populate `argv._` with everything before the `--`
|
||||
and `argv['--']` with everything after the `--`. Here's an example:
|
||||
|
||||
```
|
||||
> require('./')('one two three -- four five --six'.split(' '), { '--': true })
|
||||
{
|
||||
_: ['one', 'two', 'three'],
|
||||
'--': ['four', 'five', '--six']
|
||||
}
|
||||
```
|
||||
|
||||
Note that with `opts['--']` set, parsing for arguments still stops after the
|
||||
`--`.
|
||||
|
||||
* `opts.unknown` - a function which is invoked with a command line parameter not
|
||||
defined in the `opts` configuration object. If the function returns `false`, the
|
||||
unknown option is not added to `argv`.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install minimist
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
||||
|
||||
[package-url]: https://npmjs.org/package/minimist
|
||||
[npm-version-svg]: https://versionbadg.es/minimistjs/minimist.svg
|
||||
[npm-badge-png]: https://nodei.co/npm/minimist.png?downloads=true&stars=true
|
||||
[license-image]: https://img.shields.io/npm/l/minimist.svg
|
||||
[license-url]: LICENSE
|
||||
[downloads-image]: https://img.shields.io/npm/dm/minimist.svg
|
||||
[downloads-url]: https://npm-stat.com/charts.html?package=minimist
|
||||
[codecov-image]: https://codecov.io/gh/minimistjs/minimist/branch/main/graphs/badge.svg
|
||||
[codecov-url]: https://app.codecov.io/gh/minimistjs/minimist/
|
||||
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/minimistjs/minimist
|
||||
[actions-url]: https://github.com/minimistjs/minimist/actions
|
4
node_modules/minimist/example/parse.js
generated
vendored
Normal file
4
node_modules/minimist/example/parse.js
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
var argv = require('../')(process.argv.slice(2));
|
||||
console.log(argv);
|
263
node_modules/minimist/index.js
generated
vendored
Normal file
263
node_modules/minimist/index.js
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
|||
'use strict';
|
||||
|
||||
function hasKey(obj, keys) {
|
||||
var o = obj;
|
||||
keys.slice(0, -1).forEach(function (key) {
|
||||
o = o[key] || {};
|
||||
});
|
||||
|
||||
var key = keys[keys.length - 1];
|
||||
return key in o;
|
||||
}
|
||||
|
||||
function isNumber(x) {
|
||||
if (typeof x === 'number') { return true; }
|
||||
if ((/^0x[0-9a-f]+$/i).test(x)) { return true; }
|
||||
return (/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/).test(x);
|
||||
}
|
||||
|
||||
function isConstructorOrProto(obj, key) {
|
||||
return (key === 'constructor' && typeof obj[key] === 'function') || key === '__proto__';
|
||||
}
|
||||
|
||||
module.exports = function (args, opts) {
|
||||
if (!opts) { opts = {}; }
|
||||
|
||||
var flags = {
|
||||
bools: {},
|
||||
strings: {},
|
||||
unknownFn: null,
|
||||
};
|
||||
|
||||
if (typeof opts.unknown === 'function') {
|
||||
flags.unknownFn = opts.unknown;
|
||||
}
|
||||
|
||||
if (typeof opts.boolean === 'boolean' && opts.boolean) {
|
||||
flags.allBools = true;
|
||||
} else {
|
||||
[].concat(opts.boolean).filter(Boolean).forEach(function (key) {
|
||||
flags.bools[key] = true;
|
||||
});
|
||||
}
|
||||
|
||||
var aliases = {};
|
||||
|
||||
function aliasIsBoolean(key) {
|
||||
return aliases[key].some(function (x) {
|
||||
return flags.bools[x];
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(opts.alias || {}).forEach(function (key) {
|
||||
aliases[key] = [].concat(opts.alias[key]);
|
||||
aliases[key].forEach(function (x) {
|
||||
aliases[x] = [key].concat(aliases[key].filter(function (y) {
|
||||
return x !== y;
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
[].concat(opts.string).filter(Boolean).forEach(function (key) {
|
||||
flags.strings[key] = true;
|
||||
if (aliases[key]) {
|
||||
[].concat(aliases[key]).forEach(function (k) {
|
||||
flags.strings[k] = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var defaults = opts.default || {};
|
||||
|
||||
var argv = { _: [] };
|
||||
|
||||
function argDefined(key, arg) {
|
||||
return (flags.allBools && (/^--[^=]+$/).test(arg))
|
||||
|| flags.strings[key]
|
||||
|| flags.bools[key]
|
||||
|| aliases[key];
|
||||
}
|
||||
|
||||
function setKey(obj, keys, value) {
|
||||
var o = obj;
|
||||
for (var i = 0; i < keys.length - 1; i++) {
|
||||
var key = keys[i];
|
||||
if (isConstructorOrProto(o, key)) { return; }
|
||||
if (o[key] === undefined) { o[key] = {}; }
|
||||
if (
|
||||
o[key] === Object.prototype
|
||||
|| o[key] === Number.prototype
|
||||
|| o[key] === String.prototype
|
||||
) {
|
||||
o[key] = {};
|
||||
}
|
||||
if (o[key] === Array.prototype) { o[key] = []; }
|
||||
o = o[key];
|
||||
}
|
||||
|
||||
var lastKey = keys[keys.length - 1];
|
||||
if (isConstructorOrProto(o, lastKey)) { return; }
|
||||
if (
|
||||
o === Object.prototype
|
||||
|| o === Number.prototype
|
||||
|| o === String.prototype
|
||||
) {
|
||||
o = {};
|
||||
}
|
||||
if (o === Array.prototype) { o = []; }
|
||||
if (o[lastKey] === undefined || flags.bools[lastKey] || typeof o[lastKey] === 'boolean') {
|
||||
o[lastKey] = value;
|
||||
} else if (Array.isArray(o[lastKey])) {
|
||||
o[lastKey].push(value);
|
||||
} else {
|
||||
o[lastKey] = [o[lastKey], value];
|
||||
}
|
||||
}
|
||||
|
||||
function setArg(key, val, arg) {
|
||||
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
||||
if (flags.unknownFn(arg) === false) { return; }
|
||||
}
|
||||
|
||||
var value = !flags.strings[key] && isNumber(val)
|
||||
? Number(val)
|
||||
: val;
|
||||
setKey(argv, key.split('.'), value);
|
||||
|
||||
(aliases[key] || []).forEach(function (x) {
|
||||
setKey(argv, x.split('.'), value);
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(flags.bools).forEach(function (key) {
|
||||
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
||||
});
|
||||
|
||||
var notFlags = [];
|
||||
|
||||
if (args.indexOf('--') !== -1) {
|
||||
notFlags = args.slice(args.indexOf('--') + 1);
|
||||
args = args.slice(0, args.indexOf('--'));
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
var arg = args[i];
|
||||
var key;
|
||||
var next;
|
||||
|
||||
if ((/^--.+=/).test(arg)) {
|
||||
// Using [\s\S] instead of . because js doesn't support the
|
||||
// 'dotall' regex modifier. See:
|
||||
// http://stackoverflow.com/a/1068308/13216
|
||||
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
||||
key = m[1];
|
||||
var value = m[2];
|
||||
if (flags.bools[key]) {
|
||||
value = value !== 'false';
|
||||
}
|
||||
setArg(key, value, arg);
|
||||
} else if ((/^--no-.+/).test(arg)) {
|
||||
key = arg.match(/^--no-(.+)/)[1];
|
||||
setArg(key, false, arg);
|
||||
} else if ((/^--.+/).test(arg)) {
|
||||
key = arg.match(/^--(.+)/)[1];
|
||||
next = args[i + 1];
|
||||
if (
|
||||
next !== undefined
|
||||
&& !(/^(-|--)[^-]/).test(next)
|
||||
&& !flags.bools[key]
|
||||
&& !flags.allBools
|
||||
&& (aliases[key] ? !aliasIsBoolean(key) : true)
|
||||
) {
|
||||
setArg(key, next, arg);
|
||||
i += 1;
|
||||
} else if ((/^(true|false)$/).test(next)) {
|
||||
setArg(key, next === 'true', arg);
|
||||
i += 1;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? '' : true, arg);
|
||||
}
|
||||
} else if ((/^-[^-]+/).test(arg)) {
|
||||
var letters = arg.slice(1, -1).split('');
|
||||
|
||||
var broken = false;
|
||||
for (var j = 0; j < letters.length; j++) {
|
||||
next = arg.slice(j + 2);
|
||||
|
||||
if (next === '-') {
|
||||
setArg(letters[j], next, arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((/[A-Za-z]/).test(letters[j]) && next[0] === '=') {
|
||||
setArg(letters[j], next.slice(1), arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
(/[A-Za-z]/).test(letters[j])
|
||||
&& (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)
|
||||
) {
|
||||
setArg(letters[j], next, arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
||||
setArg(letters[j], arg.slice(j + 2), arg);
|
||||
broken = true;
|
||||
break;
|
||||
} else {
|
||||
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
|
||||
}
|
||||
}
|
||||
|
||||
key = arg.slice(-1)[0];
|
||||
if (!broken && key !== '-') {
|
||||
if (
|
||||
args[i + 1]
|
||||
&& !(/^(-|--)[^-]/).test(args[i + 1])
|
||||
&& !flags.bools[key]
|
||||
&& (aliases[key] ? !aliasIsBoolean(key) : true)
|
||||
) {
|
||||
setArg(key, args[i + 1], arg);
|
||||
i += 1;
|
||||
} else if (args[i + 1] && (/^(true|false)$/).test(args[i + 1])) {
|
||||
setArg(key, args[i + 1] === 'true', arg);
|
||||
i += 1;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? '' : true, arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
||||
argv._.push(flags.strings._ || !isNumber(arg) ? arg : Number(arg));
|
||||
}
|
||||
if (opts.stopEarly) {
|
||||
argv._.push.apply(argv._, args.slice(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(defaults).forEach(function (k) {
|
||||
if (!hasKey(argv, k.split('.'))) {
|
||||
setKey(argv, k.split('.'), defaults[k]);
|
||||
|
||||
(aliases[k] || []).forEach(function (x) {
|
||||
setKey(argv, x.split('.'), defaults[k]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (opts['--']) {
|
||||
argv['--'] = notFlags.slice();
|
||||
} else {
|
||||
notFlags.forEach(function (k) {
|
||||
argv._.push(k);
|
||||
});
|
||||
}
|
||||
|
||||
return argv;
|
||||
};
|
75
node_modules/minimist/package.json
generated
vendored
Normal file
75
node_modules/minimist/package.json
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
{
|
||||
"name": "minimist",
|
||||
"version": "1.2.8",
|
||||
"description": "parse argument options",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"@ljharb/eslint-config": "^21.0.1",
|
||||
"aud": "^2.0.2",
|
||||
"auto-changelog": "^2.4.0",
|
||||
"eslint": "=8.8.0",
|
||||
"in-publish": "^2.0.1",
|
||||
"npmignore": "^0.3.0",
|
||||
"nyc": "^10.3.2",
|
||||
"safe-publish-latest": "^2.0.0",
|
||||
"tape": "^5.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"prepack": "npmignore --auto --commentLines=auto",
|
||||
"prepublishOnly": "safe-publish-latest",
|
||||
"prepublish": "not-in-publish || npm run prepublishOnly",
|
||||
"lint": "eslint --ext=js,mjs .",
|
||||
"pretest": "npm run lint",
|
||||
"tests-only": "nyc tape 'test/**/*.js'",
|
||||
"test": "npm run tests-only",
|
||||
"posttest": "aud --production",
|
||||
"version": "auto-changelog && git add CHANGELOG.md",
|
||||
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": [
|
||||
"ie/6..latest",
|
||||
"ff/5",
|
||||
"firefox/latest",
|
||||
"chrome/10",
|
||||
"chrome/latest",
|
||||
"safari/5.1",
|
||||
"safari/latest",
|
||||
"opera/12"
|
||||
]
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/minimistjs/minimist.git"
|
||||
},
|
||||
"homepage": "https://github.com/minimistjs/minimist",
|
||||
"keywords": [
|
||||
"argv",
|
||||
"getopt",
|
||||
"parser",
|
||||
"optimist"
|
||||
],
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
},
|
||||
"license": "MIT",
|
||||
"auto-changelog": {
|
||||
"output": "CHANGELOG.md",
|
||||
"template": "keepachangelog",
|
||||
"unreleased": false,
|
||||
"commitLimit": false,
|
||||
"backfillLimit": false,
|
||||
"hideCredit": true
|
||||
},
|
||||
"publishConfig": {
|
||||
"ignore": [
|
||||
".github/workflows"
|
||||
]
|
||||
}
|
||||
}
|
34
node_modules/minimist/test/all_bool.js
generated
vendored
Normal file
34
node_modules/minimist/test/all_bool.js
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('flag boolean true (default all --args to boolean)', function (t) {
|
||||
var argv = parse(['moo', '--honk', 'cow'], {
|
||||
boolean: true,
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
honk: true,
|
||||
_: ['moo', 'cow'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.honk, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean true only affects double hyphen arguments without equals signs', function (t) {
|
||||
var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
|
||||
boolean: true,
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
honk: true,
|
||||
tacos: 'good',
|
||||
p: 55,
|
||||
_: ['moo', 'cow'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.honk, 'boolean');
|
||||
t.end();
|
||||
});
|
177
node_modules/minimist/test/bool.js
generated
vendored
Normal file
177
node_modules/minimist/test/bool.js
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('flag boolean default false', function (t) {
|
||||
var argv = parse(['moo'], {
|
||||
boolean: ['t', 'verbose'],
|
||||
default: { verbose: false, t: false },
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
verbose: false,
|
||||
t: false,
|
||||
_: ['moo'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.verbose, 'boolean');
|
||||
t.deepEqual(typeof argv.t, 'boolean');
|
||||
t.end();
|
||||
|
||||
});
|
||||
|
||||
test('boolean groups', function (t) {
|
||||
var argv = parse(['-x', '-z', 'one', 'two', 'three'], {
|
||||
boolean: ['x', 'y', 'z'],
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
x: true,
|
||||
y: false,
|
||||
z: true,
|
||||
_: ['one', 'two', 'three'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.x, 'boolean');
|
||||
t.deepEqual(typeof argv.y, 'boolean');
|
||||
t.deepEqual(typeof argv.z, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
test('boolean and alias with chainable api', function (t) {
|
||||
var aliased = ['-h', 'derp'];
|
||||
var regular = ['--herp', 'derp'];
|
||||
var aliasedArgv = parse(aliased, {
|
||||
boolean: 'herp',
|
||||
alias: { h: 'herp' },
|
||||
});
|
||||
var propertyArgv = parse(regular, {
|
||||
boolean: 'herp',
|
||||
alias: { h: 'herp' },
|
||||
});
|
||||
var expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
_: ['derp'],
|
||||
};
|
||||
|
||||
t.same(aliasedArgv, expected);
|
||||
t.same(propertyArgv, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean and alias with options hash', function (t) {
|
||||
var aliased = ['-h', 'derp'];
|
||||
var regular = ['--herp', 'derp'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'herp',
|
||||
};
|
||||
var aliasedArgv = parse(aliased, opts);
|
||||
var propertyArgv = parse(regular, opts);
|
||||
var expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
_: ['derp'],
|
||||
};
|
||||
t.same(aliasedArgv, expected);
|
||||
t.same(propertyArgv, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean and alias array with options hash', function (t) {
|
||||
var aliased = ['-h', 'derp'];
|
||||
var regular = ['--herp', 'derp'];
|
||||
var alt = ['--harp', 'derp'];
|
||||
var opts = {
|
||||
alias: { h: ['herp', 'harp'] },
|
||||
boolean: 'h',
|
||||
};
|
||||
var aliasedArgv = parse(aliased, opts);
|
||||
var propertyArgv = parse(regular, opts);
|
||||
var altPropertyArgv = parse(alt, opts);
|
||||
var expected = {
|
||||
harp: true,
|
||||
herp: true,
|
||||
h: true,
|
||||
_: ['derp'],
|
||||
};
|
||||
t.same(aliasedArgv, expected);
|
||||
t.same(propertyArgv, expected);
|
||||
t.same(altPropertyArgv, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean and alias using explicit true', function (t) {
|
||||
var aliased = ['-h', 'true'];
|
||||
var regular = ['--herp', 'true'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'h',
|
||||
};
|
||||
var aliasedArgv = parse(aliased, opts);
|
||||
var propertyArgv = parse(regular, opts);
|
||||
var expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
_: [],
|
||||
};
|
||||
|
||||
t.same(aliasedArgv, expected);
|
||||
t.same(propertyArgv, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
// regression, see https://github.com/substack/node-optimist/issues/71
|
||||
test('boolean and --x=true', function (t) {
|
||||
var parsed = parse(['--boool', '--other=true'], {
|
||||
boolean: 'boool',
|
||||
});
|
||||
|
||||
t.same(parsed.boool, true);
|
||||
t.same(parsed.other, 'true');
|
||||
|
||||
parsed = parse(['--boool', '--other=false'], {
|
||||
boolean: 'boool',
|
||||
});
|
||||
|
||||
t.same(parsed.boool, true);
|
||||
t.same(parsed.other, 'false');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean --boool=true', function (t) {
|
||||
var parsed = parse(['--boool=true'], {
|
||||
default: {
|
||||
boool: false,
|
||||
},
|
||||
boolean: ['boool'],
|
||||
});
|
||||
|
||||
t.same(parsed.boool, true);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean --boool=false', function (t) {
|
||||
var parsed = parse(['--boool=false'], {
|
||||
default: {
|
||||
boool: true,
|
||||
},
|
||||
boolean: ['boool'],
|
||||
});
|
||||
|
||||
t.same(parsed.boool, false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean using something similar to true', function (t) {
|
||||
var opts = { boolean: 'h' };
|
||||
var result = parse(['-h', 'true.txt'], opts);
|
||||
var expected = {
|
||||
h: true,
|
||||
_: ['true.txt'],
|
||||
};
|
||||
|
||||
t.same(result, expected);
|
||||
t.end();
|
||||
});
|
43
node_modules/minimist/test/dash.js
generated
vendored
Normal file
43
node_modules/minimist/test/dash.js
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('-', function (t) {
|
||||
t.plan(6);
|
||||
t.deepEqual(parse(['-n', '-']), { n: '-', _: [] });
|
||||
t.deepEqual(parse(['--nnn', '-']), { nnn: '-', _: [] });
|
||||
t.deepEqual(parse(['-']), { _: ['-'] });
|
||||
t.deepEqual(parse(['-f-']), { f: '-', _: [] });
|
||||
t.deepEqual(
|
||||
parse(['-b', '-'], { boolean: 'b' }),
|
||||
{ b: true, _: ['-'] }
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-s', '-'], { string: 's' }),
|
||||
{ s: '-', _: [] }
|
||||
);
|
||||
});
|
||||
|
||||
test('-a -- b', function (t) {
|
||||
t.plan(2);
|
||||
t.deepEqual(parse(['-a', '--', 'b']), { a: true, _: ['b'] });
|
||||
t.deepEqual(parse(['--a', '--', 'b']), { a: true, _: ['b'] });
|
||||
});
|
||||
|
||||
test('move arguments after the -- into their own `--` array', function (t) {
|
||||
t.plan(1);
|
||||
t.deepEqual(
|
||||
parse(['--name', 'John', 'before', '--', 'after'], { '--': true }),
|
||||
{ name: 'John', _: ['before'], '--': ['after'] }
|
||||
);
|
||||
});
|
||||
|
||||
test('--- option value', function (t) {
|
||||
// A multi-dash value is largely an edge case, but check the behaviour is as expected,
|
||||
// and in particular the same for short option and long option (as made consistent in Jan 2023).
|
||||
t.plan(2);
|
||||
t.deepEqual(parse(['-n', '---']), { n: '---', _: [] });
|
||||
t.deepEqual(parse(['--nnn', '---']), { nnn: '---', _: [] });
|
||||
});
|
||||
|
37
node_modules/minimist/test/default_bool.js
generated
vendored
Normal file
37
node_modules/minimist/test/default_bool.js
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var parse = require('../');
|
||||
|
||||
test('boolean default true', function (t) {
|
||||
var argv = parse([], {
|
||||
boolean: 'sometrue',
|
||||
default: { sometrue: true },
|
||||
});
|
||||
t.equal(argv.sometrue, true);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean default false', function (t) {
|
||||
var argv = parse([], {
|
||||
boolean: 'somefalse',
|
||||
default: { somefalse: false },
|
||||
});
|
||||
t.equal(argv.somefalse, false);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('boolean default to null', function (t) {
|
||||
var argv = parse([], {
|
||||
boolean: 'maybe',
|
||||
default: { maybe: null },
|
||||
});
|
||||
t.equal(argv.maybe, null);
|
||||
|
||||
var argvLong = parse(['--maybe'], {
|
||||
boolean: 'maybe',
|
||||
default: { maybe: null },
|
||||
});
|
||||
t.equal(argvLong.maybe, true);
|
||||
t.end();
|
||||
});
|
24
node_modules/minimist/test/dotted.js
generated
vendored
Normal file
24
node_modules/minimist/test/dotted.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('dotted alias', function (t) {
|
||||
var argv = parse(['--a.b', '22'], { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } });
|
||||
t.equal(argv.a.b, 22);
|
||||
t.equal(argv.aa.bb, 22);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('dotted default', function (t) {
|
||||
var argv = parse('', { default: { 'a.b': 11 }, alias: { 'a.b': 'aa.bb' } });
|
||||
t.equal(argv.a.b, 11);
|
||||
t.equal(argv.aa.bb, 11);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('dotted default with no alias', function (t) {
|
||||
var argv = parse('', { default: { 'a.b': 11 } });
|
||||
t.equal(argv.a.b, 11);
|
||||
t.end();
|
||||
});
|
32
node_modules/minimist/test/kv_short.js
generated
vendored
Normal file
32
node_modules/minimist/test/kv_short.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('short -k=v', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
var argv = parse(['-b=123']);
|
||||
t.deepEqual(argv, { b: 123, _: [] });
|
||||
});
|
||||
|
||||
test('multi short -k=v', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
var argv = parse(['-a=whatever', '-b=robots']);
|
||||
t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] });
|
||||
});
|
||||
|
||||
test('short with embedded equals -k=a=b', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
var argv = parse(['-k=a=b']);
|
||||
t.deepEqual(argv, { k: 'a=b', _: [] });
|
||||
});
|
||||
|
||||
test('short with later equals like -ab=c', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
var argv = parse(['-ab=c']);
|
||||
t.deepEqual(argv, { a: true, b: 'c', _: [] });
|
||||
});
|
33
node_modules/minimist/test/long.js
generated
vendored
Normal file
33
node_modules/minimist/test/long.js
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var parse = require('../');
|
||||
|
||||
test('long opts', function (t) {
|
||||
t.deepEqual(
|
||||
parse(['--bool']),
|
||||
{ bool: true, _: [] },
|
||||
'long boolean'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['--pow', 'xixxle']),
|
||||
{ pow: 'xixxle', _: [] },
|
||||
'long capture sp'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['--pow=xixxle']),
|
||||
{ pow: 'xixxle', _: [] },
|
||||
'long capture eq'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['--host', 'localhost', '--port', '555']),
|
||||
{ host: 'localhost', port: 555, _: [] },
|
||||
'long captures sp'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['--host=localhost', '--port=555']),
|
||||
{ host: 'localhost', port: 555, _: [] },
|
||||
'long captures eq'
|
||||
);
|
||||
t.end();
|
||||
});
|
38
node_modules/minimist/test/num.js
generated
vendored
Normal file
38
node_modules/minimist/test/num.js
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('nums', function (t) {
|
||||
var argv = parse([
|
||||
'-x', '1234',
|
||||
'-y', '5.67',
|
||||
'-z', '1e7',
|
||||
'-w', '10f',
|
||||
'--hex', '0xdeadbeef',
|
||||
'789',
|
||||
]);
|
||||
t.deepEqual(argv, {
|
||||
x: 1234,
|
||||
y: 5.67,
|
||||
z: 1e7,
|
||||
w: '10f',
|
||||
hex: 0xdeadbeef,
|
||||
_: [789],
|
||||
});
|
||||
t.deepEqual(typeof argv.x, 'number');
|
||||
t.deepEqual(typeof argv.y, 'number');
|
||||
t.deepEqual(typeof argv.z, 'number');
|
||||
t.deepEqual(typeof argv.w, 'string');
|
||||
t.deepEqual(typeof argv.hex, 'number');
|
||||
t.deepEqual(typeof argv._[0], 'number');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('already a number', function (t) {
|
||||
var argv = parse(['-x', 1234, 789]);
|
||||
t.deepEqual(argv, { x: 1234, _: [789] });
|
||||
t.deepEqual(typeof argv.x, 'number');
|
||||
t.deepEqual(typeof argv._[0], 'number');
|
||||
t.end();
|
||||
});
|
209
node_modules/minimist/test/parse.js
generated
vendored
Normal file
209
node_modules/minimist/test/parse.js
generated
vendored
Normal file
|
@ -0,0 +1,209 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('parse args', function (t) {
|
||||
t.deepEqual(
|
||||
parse(['--no-moo']),
|
||||
{ moo: false, _: [] },
|
||||
'no'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-v', 'a', '-v', 'b', '-v', 'c']),
|
||||
{ v: ['a', 'b', 'c'], _: [] },
|
||||
'multi'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('comprehensive', function (t) {
|
||||
t.deepEqual(
|
||||
parse([
|
||||
'--name=meowmers', 'bare', '-cats', 'woo',
|
||||
'-h', 'awesome', '--multi=quux',
|
||||
'--key', 'value',
|
||||
'-b', '--bool', '--no-meep', '--multi=baz',
|
||||
'--', '--not-a-flag', 'eek',
|
||||
]),
|
||||
{
|
||||
c: true,
|
||||
a: true,
|
||||
t: true,
|
||||
s: 'woo',
|
||||
h: 'awesome',
|
||||
b: true,
|
||||
bool: true,
|
||||
key: 'value',
|
||||
multi: ['quux', 'baz'],
|
||||
meep: false,
|
||||
name: 'meowmers',
|
||||
_: ['bare', '--not-a-flag', 'eek'],
|
||||
}
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean', function (t) {
|
||||
var argv = parse(['-t', 'moo'], { boolean: 't' });
|
||||
t.deepEqual(argv, { t: true, _: ['moo'] });
|
||||
t.deepEqual(typeof argv.t, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean value', function (t) {
|
||||
var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
|
||||
boolean: ['t', 'verbose'],
|
||||
default: { verbose: true },
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
verbose: false,
|
||||
t: true,
|
||||
_: ['moo'],
|
||||
});
|
||||
|
||||
t.deepEqual(typeof argv.verbose, 'boolean');
|
||||
t.deepEqual(typeof argv.t, 'boolean');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('newlines in params', function (t) {
|
||||
var args = parse(['-s', 'X\nX']);
|
||||
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||
|
||||
// reproduce in bash:
|
||||
// VALUE="new
|
||||
// line"
|
||||
// node program.js --s="$VALUE"
|
||||
args = parse(['--s=X\nX']);
|
||||
t.deepEqual(args, { _: [], s: 'X\nX' });
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('strings', function (t) {
|
||||
var s = parse(['-s', '0001234'], { string: 's' }).s;
|
||||
t.equal(s, '0001234');
|
||||
t.equal(typeof s, 'string');
|
||||
|
||||
var x = parse(['-x', '56'], { string: 'x' }).x;
|
||||
t.equal(x, '56');
|
||||
t.equal(typeof x, 'string');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('stringArgs', function (t) {
|
||||
var s = parse([' ', ' '], { string: '_' })._;
|
||||
t.same(s.length, 2);
|
||||
t.same(typeof s[0], 'string');
|
||||
t.same(s[0], ' ');
|
||||
t.same(typeof s[1], 'string');
|
||||
t.same(s[1], ' ');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('empty strings', function (t) {
|
||||
var s = parse(['-s'], { string: 's' }).s;
|
||||
t.equal(s, '');
|
||||
t.equal(typeof s, 'string');
|
||||
|
||||
var str = parse(['--str'], { string: 'str' }).str;
|
||||
t.equal(str, '');
|
||||
t.equal(typeof str, 'string');
|
||||
|
||||
var letters = parse(['-art'], {
|
||||
string: ['a', 't'],
|
||||
});
|
||||
|
||||
t.equal(letters.a, '');
|
||||
t.equal(letters.r, true);
|
||||
t.equal(letters.t, '');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('string and alias', function (t) {
|
||||
var x = parse(['--str', '000123'], {
|
||||
string: 's',
|
||||
alias: { s: 'str' },
|
||||
});
|
||||
|
||||
t.equal(x.str, '000123');
|
||||
t.equal(typeof x.str, 'string');
|
||||
t.equal(x.s, '000123');
|
||||
t.equal(typeof x.s, 'string');
|
||||
|
||||
var y = parse(['-s', '000123'], {
|
||||
string: 'str',
|
||||
alias: { str: 's' },
|
||||
});
|
||||
|
||||
t.equal(y.str, '000123');
|
||||
t.equal(typeof y.str, 'string');
|
||||
t.equal(y.s, '000123');
|
||||
t.equal(typeof y.s, 'string');
|
||||
|
||||
var z = parse(['-s123'], {
|
||||
alias: { str: ['s', 'S'] },
|
||||
string: ['str'],
|
||||
});
|
||||
|
||||
t.deepEqual(
|
||||
z,
|
||||
{ _: [], s: '123', S: '123', str: '123' },
|
||||
'opt.string works with multiple aliases'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('slashBreak', function (t) {
|
||||
t.same(
|
||||
parse(['-I/foo/bar/baz']),
|
||||
{ I: '/foo/bar/baz', _: [] }
|
||||
);
|
||||
t.same(
|
||||
parse(['-xyz/foo/bar/baz']),
|
||||
{ x: true, y: true, z: '/foo/bar/baz', _: [] }
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('alias', function (t) {
|
||||
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||
alias: { z: 'zoom' },
|
||||
});
|
||||
t.equal(argv.zoom, 55);
|
||||
t.equal(argv.z, argv.zoom);
|
||||
t.equal(argv.f, 11);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('multiAlias', function (t) {
|
||||
var argv = parse(['-f', '11', '--zoom', '55'], {
|
||||
alias: { z: ['zm', 'zoom'] },
|
||||
});
|
||||
t.equal(argv.zoom, 55);
|
||||
t.equal(argv.z, argv.zoom);
|
||||
t.equal(argv.z, argv.zm);
|
||||
t.equal(argv.f, 11);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('nested dotted objects', function (t) {
|
||||
var argv = parse([
|
||||
'--foo.bar', '3', '--foo.baz', '4',
|
||||
'--foo.quux.quibble', '5', '--foo.quux.o_O',
|
||||
'--beep.boop',
|
||||
]);
|
||||
|
||||
t.same(argv.foo, {
|
||||
bar: 3,
|
||||
baz: 4,
|
||||
quux: {
|
||||
quibble: 5,
|
||||
o_O: true,
|
||||
},
|
||||
});
|
||||
t.same(argv.beep, { boop: true });
|
||||
t.end();
|
||||
});
|
11
node_modules/minimist/test/parse_modified.js
generated
vendored
Normal file
11
node_modules/minimist/test/parse_modified.js
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('parse with modifier functions', function (t) {
|
||||
t.plan(1);
|
||||
|
||||
var argv = parse(['-b', '123'], { boolean: 'b' });
|
||||
t.deepEqual(argv, { b: true, _: [123] });
|
||||
});
|
64
node_modules/minimist/test/proto.js
generated
vendored
Normal file
64
node_modules/minimist/test/proto.js
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
'use strict';
|
||||
|
||||
/* eslint no-proto: 0 */
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('proto pollution', function (t) {
|
||||
var argv = parse(['--__proto__.x', '123']);
|
||||
t.equal({}.x, undefined);
|
||||
t.equal(argv.__proto__.x, undefined);
|
||||
t.equal(argv.x, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (array)', function (t) {
|
||||
var argv = parse(['--x', '4', '--x', '5', '--x.__proto__.z', '789']);
|
||||
t.equal({}.z, undefined);
|
||||
t.deepEqual(argv.x, [4, 5]);
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.equal(argv.x.__proto__.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (number)', function (t) {
|
||||
var argv = parse(['--x', '5', '--x.__proto__.z', '100']);
|
||||
t.equal({}.z, undefined);
|
||||
t.equal((4).z, undefined);
|
||||
t.equal(argv.x, 5);
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (string)', function (t) {
|
||||
var argv = parse(['--x', 'abc', '--x.__proto__.z', 'def']);
|
||||
t.equal({}.z, undefined);
|
||||
t.equal('...'.z, undefined);
|
||||
t.equal(argv.x, 'abc');
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (constructor)', function (t) {
|
||||
var argv = parse(['--constructor.prototype.y', '123']);
|
||||
t.equal({}.y, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (constructor function)', function (t) {
|
||||
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
|
||||
function fnToBeTested() {}
|
||||
t.equal(fnToBeTested.y, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
// powered by snyk - https://github.com/backstage/backstage/issues/10343
|
||||
test('proto pollution (constructor function) snyk', function (t) {
|
||||
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
|
||||
t.equal(function () {}.foo, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
69
node_modules/minimist/test/short.js
generated
vendored
Normal file
69
node_modules/minimist/test/short.js
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('numeric short args', function (t) {
|
||||
t.plan(2);
|
||||
t.deepEqual(parse(['-n123']), { n: 123, _: [] });
|
||||
t.deepEqual(
|
||||
parse(['-123', '456']),
|
||||
{ 1: true, 2: true, 3: 456, _: [] }
|
||||
);
|
||||
});
|
||||
|
||||
test('short', function (t) {
|
||||
t.deepEqual(
|
||||
parse(['-b']),
|
||||
{ b: true, _: [] },
|
||||
'short boolean'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['foo', 'bar', 'baz']),
|
||||
{ _: ['foo', 'bar', 'baz'] },
|
||||
'bare'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-cats']),
|
||||
{ c: true, a: true, t: true, s: true, _: [] },
|
||||
'group'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-cats', 'meow']),
|
||||
{ c: true, a: true, t: true, s: 'meow', _: [] },
|
||||
'short group next'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-h', 'localhost']),
|
||||
{ h: 'localhost', _: [] },
|
||||
'short capture'
|
||||
);
|
||||
t.deepEqual(
|
||||
parse(['-h', 'localhost', '-p', '555']),
|
||||
{ h: 'localhost', p: 555, _: [] },
|
||||
'short captures'
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('mixed short bool and capture', function (t) {
|
||||
t.same(
|
||||
parse(['-h', 'localhost', '-fp', '555', 'script.js']),
|
||||
{
|
||||
f: true, p: 555, h: 'localhost',
|
||||
_: ['script.js'],
|
||||
}
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('short and long', function (t) {
|
||||
t.deepEqual(
|
||||
parse(['-h', 'localhost', '-fp', '555', 'script.js']),
|
||||
{
|
||||
f: true, p: 555, h: 'localhost',
|
||||
_: ['script.js'],
|
||||
}
|
||||
);
|
||||
t.end();
|
||||
});
|
17
node_modules/minimist/test/stop_early.js
generated
vendored
Normal file
17
node_modules/minimist/test/stop_early.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('stops parsing on the first non-option when stopEarly is set', function (t) {
|
||||
var argv = parse(['--aaa', 'bbb', 'ccc', '--ddd'], {
|
||||
stopEarly: true,
|
||||
});
|
||||
|
||||
t.deepEqual(argv, {
|
||||
aaa: 'bbb',
|
||||
_: ['ccc', '--ddd'],
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
104
node_modules/minimist/test/unknown.js
generated
vendored
Normal file
104
node_modules/minimist/test/unknown.js
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('boolean and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'true', '--derp', 'true'];
|
||||
var regular = ['--herp', 'true', '-d', 'true'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'h',
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, ['--derp', '-d']);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('flag boolean true any double hyphen argument is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var argv = parse(['--honk', '--tacos=good', 'cow', '-p', '55'], {
|
||||
boolean: true,
|
||||
unknown: unknownFn,
|
||||
});
|
||||
t.same(unknown, ['--tacos=good', 'cow', '-p']);
|
||||
t.same(argv, {
|
||||
honk: true,
|
||||
_: [],
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('string and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'hello', '--derp', 'goodbye'];
|
||||
var regular = ['--herp', 'hello', '-d', 'moon'];
|
||||
var opts = {
|
||||
alias: { h: 'herp' },
|
||||
string: 'h',
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, ['--derp', '-d']);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('default and alias is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['-h', 'hello'];
|
||||
var regular = ['--herp', 'hello'];
|
||||
var opts = {
|
||||
default: { h: 'bar' },
|
||||
alias: { h: 'herp' },
|
||||
unknown: unknownFn,
|
||||
};
|
||||
parse(aliased, opts);
|
||||
parse(regular, opts);
|
||||
|
||||
t.same(unknown, []);
|
||||
t.end();
|
||||
unknownFn(); // exercise fn for 100% coverage
|
||||
});
|
||||
|
||||
test('value following -- is not unknown', function (t) {
|
||||
var unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
var aliased = ['--bad', '--', 'good', 'arg'];
|
||||
var opts = {
|
||||
'--': true,
|
||||
unknown: unknownFn,
|
||||
};
|
||||
var argv = parse(aliased, opts);
|
||||
|
||||
t.same(unknown, ['--bad']);
|
||||
t.same(argv, {
|
||||
'--': ['good', 'arg'],
|
||||
_: [],
|
||||
});
|
||||
t.end();
|
||||
});
|
10
node_modules/minimist/test/whitespace.js
generated
vendored
Normal file
10
node_modules/minimist/test/whitespace.js
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('whitespace should be whitespace', function (t) {
|
||||
t.plan(1);
|
||||
var x = parse(['-x', '\t']).x;
|
||||
t.equal(x, '\t');
|
||||
});
|
21
node_modules/mkdirp/LICENSE
generated
vendored
Normal file
21
node_modules/mkdirp/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
Copyright 2010 James Halliday (mail@substack.net)
|
||||
|
||||
This project is free software released under the MIT/X11 license:
|
||||
|
||||
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.
|
33
node_modules/mkdirp/bin/cmd.js
generated
vendored
Executable file
33
node_modules/mkdirp/bin/cmd.js
generated
vendored
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var mkdirp = require('../');
|
||||
var minimist = require('minimist');
|
||||
var fs = require('fs');
|
||||
|
||||
var argv = minimist(process.argv.slice(2), {
|
||||
alias: { m: 'mode', h: 'help' },
|
||||
string: [ 'mode' ]
|
||||
});
|
||||
if (argv.help) {
|
||||
fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
var paths = argv._.slice();
|
||||
var mode = argv.mode ? parseInt(argv.mode, 8) : undefined;
|
||||
|
||||
(function next () {
|
||||
if (paths.length === 0) return;
|
||||
var p = paths.shift();
|
||||
|
||||
if (mode === undefined) mkdirp(p, cb)
|
||||
else mkdirp(p, mode, cb)
|
||||
|
||||
function cb (err) {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
else next();
|
||||
}
|
||||
})();
|
12
node_modules/mkdirp/bin/usage.txt
generated
vendored
Normal file
12
node_modules/mkdirp/bin/usage.txt
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
usage: mkdirp [DIR1,DIR2..] {OPTIONS}
|
||||
|
||||
Create each supplied directory including any necessary parent directories that
|
||||
don't yet exist.
|
||||
|
||||
If the directory already exists, do nothing.
|
||||
|
||||
OPTIONS are:
|
||||
|
||||
-m, --mode If a directory needs to be created, set the mode as an octal
|
||||
permission string.
|
||||
|
102
node_modules/mkdirp/index.js
generated
vendored
Normal file
102
node_modules/mkdirp/index.js
generated
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var _0777 = parseInt('0777', 8);
|
||||
|
||||
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
|
||||
|
||||
function mkdirP (p, opts, f, made) {
|
||||
if (typeof opts === 'function') {
|
||||
f = opts;
|
||||
opts = {};
|
||||
}
|
||||
else if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = _0777
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
var cb = f || /* istanbul ignore next */ function () {};
|
||||
p = path.resolve(p);
|
||||
|
||||
xfs.mkdir(p, mode, function (er) {
|
||||
if (!er) {
|
||||
made = made || p;
|
||||
return cb(null, made);
|
||||
}
|
||||
switch (er.code) {
|
||||
case 'ENOENT':
|
||||
/* istanbul ignore if */
|
||||
if (path.dirname(p) === p) return cb(er);
|
||||
mkdirP(path.dirname(p), opts, function (er, made) {
|
||||
/* istanbul ignore if */
|
||||
if (er) cb(er, made);
|
||||
else mkdirP(p, opts, cb, made);
|
||||
});
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
xfs.stat(p, function (er2, stat) {
|
||||
// if the stat fails, then that's super weird.
|
||||
// let the original error be the failure reason.
|
||||
if (er2 || !stat.isDirectory()) cb(er, made)
|
||||
else cb(null, made);
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mkdirP.sync = function sync (p, opts, made) {
|
||||
if (!opts || typeof opts !== 'object') {
|
||||
opts = { mode: opts };
|
||||
}
|
||||
|
||||
var mode = opts.mode;
|
||||
var xfs = opts.fs || fs;
|
||||
|
||||
if (mode === undefined) {
|
||||
mode = _0777
|
||||
}
|
||||
if (!made) made = null;
|
||||
|
||||
p = path.resolve(p);
|
||||
|
||||
try {
|
||||
xfs.mkdirSync(p, mode);
|
||||
made = made || p;
|
||||
}
|
||||
catch (err0) {
|
||||
switch (err0.code) {
|
||||
case 'ENOENT' :
|
||||
made = sync(path.dirname(p), opts, made);
|
||||
sync(p, opts, made);
|
||||
break;
|
||||
|
||||
// In the case of any other error, just see if there's a dir
|
||||
// there already. If so, then hooray! If not, then something
|
||||
// is borked.
|
||||
default:
|
||||
var stat;
|
||||
try {
|
||||
stat = xfs.statSync(p);
|
||||
}
|
||||
catch (err1) /* istanbul ignore next */ {
|
||||
throw err0;
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (!stat.isDirectory()) throw err0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return made;
|
||||
};
|
33
node_modules/mkdirp/package.json
generated
vendored
Normal file
33
node_modules/mkdirp/package.json
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "mkdirp",
|
||||
"description": "Recursively mkdir, like `mkdir -p`",
|
||||
"version": "0.5.6",
|
||||
"publishConfig": {
|
||||
"tag": "legacy"
|
||||
},
|
||||
"author": "James Halliday <mail@substack.net> (http://substack.net)",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"mkdir",
|
||||
"directory"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/substack/node-mkdirp.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^16.0.1"
|
||||
},
|
||||
"bin": "bin/cmd.js",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"bin",
|
||||
"index.js"
|
||||
]
|
||||
}
|
100
node_modules/mkdirp/readme.markdown
generated
vendored
Normal file
100
node_modules/mkdirp/readme.markdown
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
# mkdirp
|
||||
|
||||
Like `mkdir -p`, but in node.js!
|
||||
|
||||
[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)
|
||||
|
||||
# example
|
||||
|
||||
## pow.js
|
||||
|
||||
```js
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
mkdirp('/tmp/foo/bar/baz', function (err) {
|
||||
if (err) console.error(err)
|
||||
else console.log('pow!')
|
||||
});
|
||||
```
|
||||
|
||||
Output
|
||||
|
||||
```
|
||||
pow!
|
||||
```
|
||||
|
||||
And now /tmp/foo/bar/baz exists, huzzah!
|
||||
|
||||
# methods
|
||||
|
||||
```js
|
||||
var mkdirp = require('mkdirp');
|
||||
```
|
||||
|
||||
## mkdirp(dir, opts, cb)
|
||||
|
||||
Create a new directory and any necessary subdirectories at `dir` with octal
|
||||
permission string `opts.mode`. If `opts` is a non-object, it will be treated as
|
||||
the `opts.mode`.
|
||||
|
||||
If `opts.mode` isn't specified, it defaults to `0777`.
|
||||
|
||||
`cb(err, made)` fires with the error or the first directory `made`
|
||||
that had to be created, if any.
|
||||
|
||||
You can optionally pass in an alternate `fs` implementation by passing in
|
||||
`opts.fs`. Your implementation should have `opts.fs.mkdir(path, mode, cb)` and
|
||||
`opts.fs.stat(path, cb)`.
|
||||
|
||||
## mkdirp.sync(dir, opts)
|
||||
|
||||
Synchronously create a new directory and any necessary subdirectories at `dir`
|
||||
with octal permission string `opts.mode`. If `opts` is a non-object, it will be
|
||||
treated as the `opts.mode`.
|
||||
|
||||
If `opts.mode` isn't specified, it defaults to `0777`.
|
||||
|
||||
Returns the first directory that had to be created, if any.
|
||||
|
||||
You can optionally pass in an alternate `fs` implementation by passing in
|
||||
`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` and
|
||||
`opts.fs.statSync(path)`.
|
||||
|
||||
# usage
|
||||
|
||||
This package also ships with a `mkdirp` command.
|
||||
|
||||
```
|
||||
usage: mkdirp [DIR1,DIR2..] {OPTIONS}
|
||||
|
||||
Create each supplied directory including any necessary parent directories that
|
||||
don't yet exist.
|
||||
|
||||
If the directory already exists, do nothing.
|
||||
|
||||
OPTIONS are:
|
||||
|
||||
-m, --mode If a directory needs to be created, set the mode as an octal
|
||||
permission string.
|
||||
|
||||
```
|
||||
|
||||
# install
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install mkdirp
|
||||
```
|
||||
|
||||
to get the library, or
|
||||
|
||||
```
|
||||
npm install -g mkdirp
|
||||
```
|
||||
|
||||
to get the command.
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
17
node_modules/multer/LICENSE
generated
vendored
Normal file
17
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.
|
333
node_modules/multer/README.md
generated
vendored
Normal file
333
node_modules/multer/README.md
generated
vendored
Normal file
|
@ -0,0 +1,333 @@
|
|||
# Multer [![Build Status](https://travis-ci.org/expressjs/multer.svg?branch=master)](https://travis-ci.org/expressjs/multer) [![NPM version](https://badge.fury.io/js/multer.svg)](https://badge.fury.io/js/multer) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](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:
|
||||
|
||||
- [Español](https://github.com/expressjs/multer/blob/master/doc/README-es.md) (Spanish)
|
||||
- [简体中文](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)
|
||||
- [Русский язык](https://github.com/expressjs/multer/blob/master/doc/README-ru.md) (Russian)
|
||||
- [Việt Nam](https://github.com/expressjs/multer/blob/master/doc/README-vi.md) (Vietnam)
|
||||
- [Português](https://github.com/expressjs/multer/blob/master/doc/README-pt-br.md) (Portuguese Brazil)
|
||||
|
||||
## 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
|
||||
const express = require('express')
|
||||
const multer = require('multer')
|
||||
const upload = multer({ dest: 'uploads/' })
|
||||
|
||||
const 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
|
||||
})
|
||||
|
||||
const 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
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const multer = require('multer')
|
||||
const upload = multer()
|
||||
|
||||
app.post('/profile', upload.none(), function (req, res, next) {
|
||||
// req.body contains the text fields
|
||||
})
|
||||
```
|
||||
|
||||
Here's an example on how multer is used an HTML form. Take special note of the `enctype="multipart/form-data"` and `name="uploaded_file"` fields:
|
||||
|
||||
```html
|
||||
<form action="/stats" enctype="multipart/form-data" method="post">
|
||||
<div class="form-group">
|
||||
<input type="file" class="form-control-file" name="uploaded_file">
|
||||
<input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
|
||||
<input type="submit" value="Get me the stats!" class="btn btn-default">
|
||||
</div>
|
||||
</form>
|
||||
```
|
||||
|
||||
Then in your javascript file you would add these lines to access both the file and the body. It is important that you use the `name` field value from the form in your upload function. This tells multer which field on the request it should look for the files in. If these fields aren't the same in the HTML form and on your server, your upload will fail:
|
||||
|
||||
```javascript
|
||||
const multer = require('multer')
|
||||
const upload = multer({ dest: './public/data/uploads/' })
|
||||
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
|
||||
// req.file is the name of your file in the form above, here 'uploaded_file'
|
||||
// req.body will hold the text fields, if there were any
|
||||
console.log(req.file, req.body)
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 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
|
||||
const 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
|
||||
const storage = multer.diskStorage({
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, '/tmp/my-uploads')
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
|
||||
cb(null, file.fieldname + '-' + uniqueSuffix)
|
||||
}
|
||||
})
|
||||
|
||||
const 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.
|
||||
|
||||
For understanding the calling convention used in the callback (needing to pass
|
||||
null as the first param), refer to
|
||||
[Node.js error handling](https://www.joyent.com/node-js/production/design/errors)
|
||||
|
||||
#### `MemoryStorage`
|
||||
|
||||
The memory storage engine stores the files in memory as `Buffer` objects. It
|
||||
doesn't have any options.
|
||||
|
||||
```javascript
|
||||
const storage = multer.memoryStorage()
|
||||
const 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 (in bytes) | 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/multer-error.js), you can use the `MulterError` class that is attached to the `multer` object itself (e.g. `err instanceof multer.MulterError`).
|
||||
|
||||
```javascript
|
||||
const multer = require('multer')
|
||||
const 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
node_modules/multer/index.js
generated
vendored
Normal file
104
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
node_modules/multer/lib/counter.js
generated
vendored
Normal file
28
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
node_modules/multer/lib/file-appender.js
generated
vendored
Normal file
67
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
|
173
node_modules/multer/lib/make-middleware.js
generated
vendored
Normal file
173
node_modules/multer/lib/make-middleware.js
generated
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
var is = require('type-is')
|
||||
var Busboy = require('busboy')
|
||||
var extend = require('xtend')
|
||||
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 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 = 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)
|
||||
busboy.removeAllListeners()
|
||||
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, { nameTruncated, valueTruncated }) {
|
||||
if (fieldname == null) return abortWithCode('MISSING_FIELD_NAME')
|
||||
if (nameTruncated) 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 && Object.prototype.hasOwnProperty.call(limits, '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 && Object.prototype.hasOwnProperty.call(limits, '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('close', function () {
|
||||
readFinished = true
|
||||
indicateDone()
|
||||
})
|
||||
|
||||
req.pipe(busboy)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = makeMiddleware
|
24
node_modules/multer/lib/multer-error.js
generated
vendored
Normal file
24
node_modules/multer/lib/multer-error.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
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',
|
||||
MISSING_FIELD_NAME: 'Field name missing'
|
||||
}
|
||||
|
||||
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
node_modules/multer/lib/remove-uploaded-files.js
generated
vendored
Normal file
28
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
|
52
node_modules/multer/package.json
generated
vendored
Normal file
52
node_modules/multer/package.json
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"name": "multer",
|
||||
"description": "Middleware for handling `multipart/form-data`.",
|
||||
"version": "1.4.5-lts.1",
|
||||
"contributors": [
|
||||
"Hage Yaapa <captain@hacksparrow.com> (http://www.hacksparrow.com)",
|
||||
"Jaret Pfluger <https://github.com/jpfluger>",
|
||||
"Linus Unnebäck <linus@folkdatorn.se>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "expressjs/multer",
|
||||
"keywords": [
|
||||
"form",
|
||||
"post",
|
||||
"multipart",
|
||||
"form-data",
|
||||
"formdata",
|
||||
"express",
|
||||
"middleware"
|
||||
],
|
||||
"dependencies": {
|
||||
"append-field": "^1.0.0",
|
||||
"busboy": "^1.0.0",
|
||||
"concat-stream": "^1.5.2",
|
||||
"mkdirp": "^0.5.4",
|
||||
"object-assign": "^4.1.1",
|
||||
"type-is": "^1.6.4",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"deep-equal": "^2.0.3",
|
||||
"express": "^4.13.1",
|
||||
"form-data": "^1.0.0-rc1",
|
||||
"fs-temp": "^1.1.2",
|
||||
"mocha": "^3.5.3",
|
||||
"rimraf": "^2.4.1",
|
||||
"standard": "^14.3.3",
|
||||
"testdata-w3c-json-form": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"index.js",
|
||||
"storage/",
|
||||
"lib/"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "standard && mocha"
|
||||
}
|
||||
}
|
66
node_modules/multer/storage/disk.js
generated
vendored
Normal file
66
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.randomBytes(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
node_modules/multer/storage/memory.js
generated
vendored
Normal file
21
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)
|
||||
}
|
90
node_modules/object-assign/index.js
generated
vendored
Normal file
90
node_modules/object-assign/index.js
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
/* eslint-disable no-unused-vars */
|
||||
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
|
||||
|
||||
function toObject(val) {
|
||||
if (val === null || val === undefined) {
|
||||
throw new TypeError('Object.assign cannot be called with null or undefined');
|
||||
}
|
||||
|
||||
return Object(val);
|
||||
}
|
||||
|
||||
function shouldUseNative() {
|
||||
try {
|
||||
if (!Object.assign) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Detect buggy property enumeration order in older V8 versions.
|
||||
|
||||
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
|
||||
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
|
||||
test1[5] = 'de';
|
||||
if (Object.getOwnPropertyNames(test1)[0] === '5') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
||||
var test2 = {};
|
||||
for (var i = 0; i < 10; i++) {
|
||||
test2['_' + String.fromCharCode(i)] = i;
|
||||
}
|
||||
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
|
||||
return test2[n];
|
||||
});
|
||||
if (order2.join('') !== '0123456789') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
||||
var test3 = {};
|
||||
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
|
||||
test3[letter] = letter;
|
||||
});
|
||||
if (Object.keys(Object.assign({}, test3)).join('') !==
|
||||
'abcdefghijklmnopqrst') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
// We don't expect any of the above to throw, but better to be safe.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = shouldUseNative() ? Object.assign : function (target, source) {
|
||||
var from;
|
||||
var to = toObject(target);
|
||||
var symbols;
|
||||
|
||||
for (var s = 1; s < arguments.length; s++) {
|
||||
from = Object(arguments[s]);
|
||||
|
||||
for (var key in from) {
|
||||
if (hasOwnProperty.call(from, key)) {
|
||||
to[key] = from[key];
|
||||
}
|
||||
}
|
||||
|
||||
if (getOwnPropertySymbols) {
|
||||
symbols = getOwnPropertySymbols(from);
|
||||
for (var i = 0; i < symbols.length; i++) {
|
||||
if (propIsEnumerable.call(from, symbols[i])) {
|
||||
to[symbols[i]] = from[symbols[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
};
|
21
node_modules/object-assign/license
generated
vendored
Normal file
21
node_modules/object-assign/license
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.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.
|
42
node_modules/object-assign/package.json
generated
vendored
Normal file
42
node_modules/object-assign/package.json
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "object-assign",
|
||||
"version": "4.1.1",
|
||||
"description": "ES2015 `Object.assign()` ponyfill",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/object-assign",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava",
|
||||
"bench": "matcha bench.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"object",
|
||||
"assign",
|
||||
"extend",
|
||||
"properties",
|
||||
"es2015",
|
||||
"ecmascript",
|
||||
"harmony",
|
||||
"ponyfill",
|
||||
"prollyfill",
|
||||
"polyfill",
|
||||
"shim",
|
||||
"browser"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^0.16.0",
|
||||
"lodash": "^4.16.4",
|
||||
"matcha": "^0.7.0",
|
||||
"xo": "^0.16.0"
|
||||
}
|
||||
}
|
61
node_modules/object-assign/readme.md
generated
vendored
Normal file
61
node_modules/object-assign/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign)
|
||||
|
||||
> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com)
|
||||
|
||||
|
||||
## Use the built-in
|
||||
|
||||
Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari),
|
||||
support `Object.assign()` :tada:. If you target only those environments, then by all
|
||||
means, use `Object.assign()` instead of this package.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save object-assign
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const objectAssign = require('object-assign');
|
||||
|
||||
objectAssign({foo: 0}, {bar: 1});
|
||||
//=> {foo: 0, bar: 1}
|
||||
|
||||
// multiple sources
|
||||
objectAssign({foo: 0}, {bar: 1}, {baz: 2});
|
||||
//=> {foo: 0, bar: 1, baz: 2}
|
||||
|
||||
// overwrites equal keys
|
||||
objectAssign({foo: 0}, {foo: 1}, {foo: 2});
|
||||
//=> {foo: 2}
|
||||
|
||||
// ignores null and undefined sources
|
||||
objectAssign({foo: 0}, null, {bar: 1}, undefined);
|
||||
//=> {foo: 0, bar: 1}
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### objectAssign(target, [source, ...])
|
||||
|
||||
Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones.
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign)
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()`
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](https://sindresorhus.com)
|
45
node_modules/process-nextick-args/index.js
generated
vendored
Normal file
45
node_modules/process-nextick-args/index.js
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
if (typeof process === 'undefined' ||
|
||||
!process.version ||
|
||||
process.version.indexOf('v0.') === 0 ||
|
||||
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
|
||||
module.exports = { nextTick: nextTick };
|
||||
} else {
|
||||
module.exports = process
|
||||
}
|
||||
|
||||
function nextTick(fn, arg1, arg2, arg3) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError('"callback" argument must be a function');
|
||||
}
|
||||
var len = arguments.length;
|
||||
var args, i;
|
||||
switch (len) {
|
||||
case 0:
|
||||
case 1:
|
||||
return process.nextTick(fn);
|
||||
case 2:
|
||||
return process.nextTick(function afterTickOne() {
|
||||
fn.call(null, arg1);
|
||||
});
|
||||
case 3:
|
||||
return process.nextTick(function afterTickTwo() {
|
||||
fn.call(null, arg1, arg2);
|
||||
});
|
||||
case 4:
|
||||
return process.nextTick(function afterTickThree() {
|
||||
fn.call(null, arg1, arg2, arg3);
|
||||
});
|
||||
default:
|
||||
args = new Array(len - 1);
|
||||
i = 0;
|
||||
while (i < args.length) {
|
||||
args[i++] = arguments[i];
|
||||
}
|
||||
return process.nextTick(function afterTick() {
|
||||
fn.apply(null, args);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
19
node_modules/process-nextick-args/license.md
generated
vendored
Normal file
19
node_modules/process-nextick-args/license.md
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright (c) 2015 Calvin Metcalf
|
||||
|
||||
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.**
|
25
node_modules/process-nextick-args/package.json
generated
vendored
Normal file
25
node_modules/process-nextick-args/package.json
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "process-nextick-args",
|
||||
"version": "2.0.1",
|
||||
"description": "process.nextTick but always with args",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/calvinmetcalf/process-nextick-args.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/calvinmetcalf/process-nextick-args/issues"
|
||||
},
|
||||
"homepage": "https://github.com/calvinmetcalf/process-nextick-args",
|
||||
"devDependencies": {
|
||||
"tap": "~0.2.6"
|
||||
}
|
||||
}
|
18
node_modules/process-nextick-args/readme.md
generated
vendored
Normal file
18
node_modules/process-nextick-args/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
process-nextick-args
|
||||
=====
|
||||
|
||||
[![Build Status](https://travis-ci.org/calvinmetcalf/process-nextick-args.svg?branch=master)](https://travis-ci.org/calvinmetcalf/process-nextick-args)
|
||||
|
||||
```bash
|
||||
npm install --save process-nextick-args
|
||||
```
|
||||
|
||||
Always be able to pass arguments to process.nextTick, no matter the platform
|
||||
|
||||
```js
|
||||
var pna = require('process-nextick-args');
|
||||
|
||||
pna.nextTick(function (a, b, c) {
|
||||
console.log(a, b, c);
|
||||
}, 'step', 3, 'profit');
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue