formdata-node
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -31,2 +31,4 @@ "use strict"; | ||
var _class, _temp, _initialiseProps; | ||
var _stream = require("stream"); | ||
@@ -60,2 +62,6 @@ | ||
var _getType = require("./util/getType"); | ||
var _getType2 = _interopRequireDefault(_getType); | ||
var _isString = require("./util/isString"); | ||
@@ -65,2 +71,6 @@ | ||
var _isObject = require("./util/isObject"); | ||
var _isObject2 = _interopRequireDefault(_isObject); | ||
var _isBuffer = require("./util/isBuffer"); | ||
@@ -80,74 +90,22 @@ | ||
let FormData = class FormData { | ||
constructor() { | ||
this.__getMime = filename => _mimeTypes2.default.lookup(filename) || this.__defaultContentType; | ||
const isArray = Array.isArray; | ||
this.__getFooter = () => Buffer.from((0, _concat2.default)(this.__dashes, this.__boundary, this.__dashes, this.__carriage.repeat(2))); | ||
/** | ||
* FormData implementation for Node.js environments. | ||
* Bult over Readable stream and async generators. | ||
* Can be useful for universavl (isomorphic) applications | ||
* or in Node.js HTTP client that sending a data in multipart/form-data format. | ||
* | ||
* @api public | ||
*/ | ||
let FormData = (_temp = _class = class FormData { | ||
/** | ||
* @param {array} fields – an optional FormData initial fields. | ||
* Each initial field should be passed as an array with 3 elemtnts | ||
* as a collection of the objects with "name", "value" and "filename" props. | ||
* See the FormData#append for more info about the available format. | ||
*/ | ||
constructor(fields = null) { | ||
_initialiseProps.call(this); | ||
this.__read = () => { | ||
const onFulfilled = curr => { | ||
if (curr.done) { | ||
return this.__stream.push(null); | ||
} | ||
const chunk = curr.value; | ||
this.__stream.push((0, _isBuffer2.default)(chunk) ? chunk : Buffer.from(String(chunk))); | ||
}; | ||
const onRejected = err => this.__stream.emit("error", err); | ||
this.__curr.next().then(onFulfilled, onRejected); | ||
}; | ||
this.append = (name, value, filename) => this.__setField(name, value, filename, 1); | ||
this.set = (name, value, filename) => this.__setField(name, value, filename); | ||
this.has = name => this.__contents.has(name); | ||
this.get = name => { | ||
const field = this.__contents.get(name); | ||
// NOTE: This method should return only the first field value. | ||
// I should add this behaviour somehow | ||
if (!field) { | ||
return void 0; | ||
} | ||
const [value] = field.values; | ||
return (0, _isBuffer2.default)(value) || (0, _isReadable2.default)(value) ? value : String(value); | ||
}; | ||
this.getAll = name => { | ||
const res = []; | ||
const field = this.__contents.get(name); | ||
if (field) { | ||
for (const value of field.values) { | ||
res.push((0, _isBuffer2.default)(value) || (0, _isReadable2.default)(value) ? value : String(value)); | ||
} | ||
} | ||
return res; | ||
}; | ||
this.delete = name => void this.__contents.delete(name); | ||
this.pipe = (dest, options) => this.__stream.pipe(dest, options); | ||
this.on = (name, fn) => { | ||
this.__stream.on(name, fn); | ||
return this; | ||
}; | ||
this.forEach = (fn, ctx = null) => { | ||
for (const [name, value] of this.entries()) { | ||
fn.call(ctx, value, name, this); | ||
} | ||
}; | ||
(0, _bind2.default)([_iterator2.default, _symbol2.default.asyncIterator, "toString", "toJSON", "inspect", "keys", "values", "entries"], this); | ||
@@ -169,2 +127,6 @@ | ||
this.__stream = new _stream.Readable({ read }); | ||
if (isArray(fields)) { | ||
this.__appendFromInitialFields(fields); | ||
} | ||
} | ||
@@ -179,2 +141,4 @@ | ||
* @return {boolean} | ||
* | ||
* @public | ||
*/ | ||
@@ -185,2 +149,10 @@ static isFormData(value) { | ||
/** | ||
* @private | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
__getHeader(name, filename) { | ||
@@ -196,3 +168,3 @@ const head = [this.__dashes, this.__boundary, this.__carriage, "Content-Disposition: form-data; ", `name="${name}"`]; | ||
return Buffer.from((0, _concat2.default)(head)); | ||
return (0, _concat2.default)(...head); | ||
} | ||
@@ -203,2 +175,9 @@ | ||
*/ | ||
/** | ||
* Get each field from internal Map | ||
* | ||
* @private | ||
*/ | ||
__getField() { | ||
@@ -221,4 +200,6 @@ var _this = this; | ||
// Get field header | ||
yield _this.__getHeader(name, filename); | ||
// Get the field body | ||
for (const value of values) { | ||
@@ -232,2 +213,3 @@ if ((0, _isReadable2.default)(value)) { | ||
// Add trailing carriage | ||
yield _this.__carriage; | ||
@@ -241,5 +223,16 @@ } | ||
* | ||
* @return {void} | ||
* | ||
* @private | ||
*/ | ||
/** | ||
* Append initial fields | ||
* | ||
* @param {array} fields | ||
* | ||
* @return {void} | ||
* | ||
* @private | ||
*/ | ||
@@ -249,15 +242,24 @@ | ||
/** | ||
* Set a new filed to internal FormData Map object | ||
* Appends a new value onto an existing key inside a FormData object, | ||
* or adds the key if it does not already exist. | ||
* | ||
* @param {string} name | ||
* @param {any} value | ||
* @param {string} filename | ||
* @param {boolean} append | ||
* @param {string} name – The name of the field whose data | ||
* is contained in value | ||
* | ||
* @param {any} value – The field value. You can pass any primitive type | ||
* (including null and undefined), Buffer or Readable stream. | ||
* Note that Arrays and Object will be converted to string | ||
* by using String function. | ||
* | ||
* @param {string} [filename = undefined] A filename of given field. | ||
* Can be added only for Buffer and Readable | ||
* | ||
* @return {void} | ||
* | ||
* @private | ||
*/ | ||
__setField(name, value, filename, append = false) { | ||
(0, _invariant2.default)(!(0, _isString2.default)(name), TypeError, "Field name should be a string. Received %s", typeof name); | ||
(0, _invariant2.default)(!(0, _isString2.default)(name), TypeError, "Field name should be a string. Received %s", (0, _getType2.default)(name)); | ||
(0, _invariant2.default)(filename && !(0, _isString2.default)(filename), TypeError, "Filename should be a string (if passed). Received %s", typeof filename); | ||
(0, _invariant2.default)(filename && !(0, _isString2.default)(filename), TypeError, "Filename should be a string (if passed). Received %s", (0, _getType2.default)(filename)); | ||
@@ -268,2 +270,5 @@ // Try to get a filename for buffer and Readable values | ||
} else if ((0, _isReadable2.default)(value) && (value.path || filename)) { | ||
// Readable stream which created from fs.createReadStream | ||
// have a "path" property. So, we can get a "filename" | ||
// from the stream itself. | ||
filename = (0, _path.basename)(value.path || filename); | ||
@@ -301,2 +306,4 @@ } | ||
* @return {string} | ||
* | ||
* @public | ||
*/ | ||
@@ -311,2 +318,4 @@ get boundary() { | ||
* @return {stream.Readable} | ||
* | ||
* @public | ||
*/ | ||
@@ -318,9 +327,19 @@ get stream() { | ||
/** | ||
* Set new field on FormData | ||
* Appends a new value onto an existing key inside a FormData object, | ||
* or adds the key if it does not already exist. | ||
* | ||
* @param {string} name – field name | ||
* @param {any} value – field value | ||
* @param {string} filename | ||
* @param {string} name – The name of the field whose data | ||
* is contained in value | ||
* | ||
* @param {any} value – The field value. You can pass any primitive type | ||
* (including null and undefined), Buffer or Readable stream. | ||
* Note that Arrays and Object will be converted to string | ||
* by using String function. | ||
* | ||
* @param {string} [filename = undefined] A filename of given field. | ||
* Can be added only for Buffer and Readable | ||
* | ||
* @return {void} | ||
* | ||
* @public | ||
*/ | ||
@@ -330,10 +349,78 @@ | ||
/** | ||
* Check if the value with given key exists | ||
* Set a new value for an existing key inside FormData, | ||
* or add the new field if it does not already exist. | ||
* | ||
* @param {string} name – name of a value you are looking for | ||
* @param {string} name – The name of the field whose data | ||
* is contained in value | ||
* | ||
* @param {any} value – The field value. You can pass any primitive type | ||
* (including null and undefined), Buffer or Readable stream. | ||
* Note that Arrays and Object will be converted to string | ||
* by using String function. | ||
* | ||
* @param {string} [filename = undefined] A filename of given field. | ||
* Can be added only for Buffer and Readable | ||
* | ||
* @return {void} | ||
* | ||
* @public | ||
*/ | ||
/** | ||
* Check if a field with the given name exists inside FormData. | ||
* | ||
* @param {string} name – A name of the field you want to test for. | ||
* | ||
* @return {boolean} | ||
* | ||
* @public | ||
*/ | ||
/** | ||
* Returns the first value associated with the given name. | ||
* Buffer and Readable values will be returned as-is. | ||
* | ||
* @param {string} name – A name of the value you want to retrieve. | ||
* | ||
* @public | ||
*/ | ||
/** | ||
* Returns all the values associated with | ||
* a given key from within a FormData object. | ||
* | ||
* @param {string} name – A name of the value you want to retrieve. | ||
* | ||
* @public | ||
*/ | ||
/** | ||
* Deletes a key and its value(s) from a FormData object. | ||
* | ||
* @param {string} name – The name of the key you want to delete. | ||
* | ||
* @public | ||
*/ | ||
/** | ||
* Executes a given callback for each field of the FormData instance | ||
* | ||
* @param {function} fn – Function to execute for each element, | ||
* taking three arguments: | ||
* + {any} value – A value(s) of the current field. | ||
* + {string} – Name of the current field. | ||
* + {FormData} fd – The FormData instance that forEach | ||
* is being applied to | ||
* | ||
* @param {any} [ctx = null] | ||
* | ||
* @public | ||
*/ | ||
toString() { | ||
@@ -344,3 +431,3 @@ return `[object ${this.constructor.name}]`; | ||
toJSON() { | ||
return this.constructor.name; | ||
return `[object ${this.constructor.name}]`; | ||
} | ||
@@ -380,5 +467,7 @@ | ||
* This method allows to read a content from internal stream | ||
* using async generators and for-await..of APIs | ||
* using async generators and for-await-of APIs | ||
* | ||
* @return {StreamIterator} | ||
* | ||
* @public | ||
*/ | ||
@@ -388,3 +477,83 @@ [_symbol2.default.asyncIterator]() { | ||
} | ||
}; | ||
}, _initialiseProps = function () { | ||
this.__getMime = filename => _mimeTypes2.default.lookup(filename) || this.__defaultContentType; | ||
this.__getFooter = () => (0, _concat2.default)(this.__dashes, this.__boundary, this.__dashes, this.__carriage.repeat(2)); | ||
this.__read = () => { | ||
const onFulfilled = curr => { | ||
if (curr.done) { | ||
return this.__stream.push(null); | ||
} | ||
const chunk = curr.value; | ||
this.__stream.push((0, _isBuffer2.default)(chunk) ? chunk : Buffer.from(String(chunk))); | ||
}; | ||
const onRejected = err => this.__stream.emit("error", err); | ||
this.__curr.next().then(onFulfilled, onRejected); | ||
}; | ||
this.__appendFromInitialFields = fields => { | ||
for (let field of fields) { | ||
// If the "field" is object, get its properties and reassign them as array | ||
if ((0, _isObject2.default)(field)) { | ||
field = [field.name, field.value, field.filename]; | ||
} | ||
this.append(...field); | ||
} | ||
}; | ||
this.append = (name, value, filename) => this.__setField(name, value, filename, 1); | ||
this.set = (name, value, filename) => this.__setField(name, value, filename); | ||
this.has = name => this.__contents.has(name); | ||
this.get = name => { | ||
const field = this.__contents.get(name); | ||
// I should add this behaviour somehow | ||
if (!field) { | ||
return void 0; | ||
} | ||
const [value] = field.values; | ||
return (0, _isBuffer2.default)(value) || (0, _isReadable2.default)(value) ? value : String(value); | ||
}; | ||
this.getAll = name => { | ||
const res = []; | ||
const field = this.__contents.get(name); | ||
if (field) { | ||
for (const value of field.values) { | ||
res.push((0, _isBuffer2.default)(value) || (0, _isReadable2.default)(value) ? value : String(value)); | ||
} | ||
} | ||
return res; | ||
}; | ||
this.delete = name => void this.__contents.delete(name); | ||
this.pipe = (dest, options) => this.__stream.pipe(dest, options); | ||
this.on = (name, fn) => { | ||
this.__stream.on(name, fn); | ||
return this; | ||
}; | ||
this.forEach = (fn, ctx = null) => { | ||
for (const [name, value] of this) { | ||
fn.call(ctx, value, name, this); | ||
} | ||
}; | ||
}, _temp); | ||
exports.default = FormData; |
{ | ||
"name": "formdata-node", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "FormData implementation for Node.js. Built over Readable stream and async generators.", | ||
@@ -46,3 +46,3 @@ "repository": "octet-stream/form-data", | ||
"codecov": "2.3.1", | ||
"eslint": "4.8.0", | ||
"eslint": "4.9.0", | ||
"eslint-plugin-ava": "4.2.2", | ||
@@ -49,0 +49,0 @@ "husky": "0.14.3", |
@@ -26,6 +26,21 @@ # FormData | ||
### `constructor FormData()` | ||
### `constructor FormData([fields])` | ||
Initialize new FormData instance | ||
- **{array}** [fields = null] – an optional FormData initial fields. | ||
Each initial field should be passed as an array with 3 elemtnts | ||
as a collection of the objects with "name", "value" and "filename" props. | ||
See the FormData#append for more info about the available format. | ||
#### Instance properties | ||
##### `get boundary() -> {string}` | ||
Returns a boundary string of the current FormData instance. | ||
##### `get stream() -> {stream.Readable}` | ||
Returns an internal Readable stream. | ||
#### Instance methods | ||
@@ -60,3 +75,3 @@ | ||
- **{string}** – A name of the value you want to retrieve. | ||
- **{string}** name – A name of the value you want to retrieve. | ||
@@ -67,3 +82,3 @@ ##### `getAll(name) -> {string[] | Buffer[] | stream.Readable[]}` | ||
- **{string}** – A name of the value you want to retrieve. | ||
- **{string}** name – A name of the value you want to retrieve. | ||
@@ -82,2 +97,12 @@ ##### `has(name) -> {boolean}` | ||
#### `forEach(callback[, ctx]) -> {void}` | ||
Executes a given **callback** for each field of the FormData instance | ||
- **{function}** callback – Function to execute for each element, taking three arguments: | ||
+ **{any}** value – A value(s) of the current field. | ||
+ **{string}** name – Name of the current field. | ||
+ **{FormData}** fd – The FormData instance that **forEach** is being applied to | ||
- **{any}** [ctx = null] – Value to use as **this** context when executing the given **callback** | ||
##### `keys() -> {iterator}` | ||
@@ -99,2 +124,7 @@ | ||
##### `[Symbol.asyncIterator]() -> {asyncIterator}` | ||
Returns an async iterator which allows to read the data from internal Readable stream using **for-await** syntax. | ||
Read the [async iteration proposal](https://github.com/tc39/proposal-async-iteration) for more info about async generator functions. | ||
## Related packages | ||
@@ -101,0 +131,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28454
579
130
14