formdata-node
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -7,2 +7,6 @@ "use strict"; | ||
var _asyncGenerator2 = require("babel-runtime/helpers/asyncGenerator"); | ||
var _asyncGenerator3 = _interopRequireDefault(_asyncGenerator2); | ||
var _asyncIterator2 = require("babel-runtime/helpers/asyncIterator"); | ||
@@ -12,5 +16,5 @@ | ||
var _asyncGenerator2 = require("babel-runtime/helpers/asyncGenerator"); | ||
var _asyncGeneratorDelegate2 = require("babel-runtime/helpers/asyncGeneratorDelegate"); | ||
var _asyncGenerator3 = _interopRequireDefault(_asyncGenerator2); | ||
var _asyncGeneratorDelegate3 = _interopRequireDefault(_asyncGeneratorDelegate2); | ||
@@ -25,5 +29,5 @@ var _map = require("babel-runtime/core-js/map"); | ||
var _iterator2 = require("babel-runtime/core-js/symbol/iterator"); | ||
var _iterator = require("babel-runtime/core-js/symbol/iterator"); | ||
var _iterator3 = _interopRequireDefault(_iterator2); | ||
var _iterator2 = _interopRequireDefault(_iterator); | ||
@@ -50,2 +54,14 @@ var _stream = require("stream"); | ||
var _nextTick = require("./util/nextTick"); | ||
var _nextTick2 = _interopRequireDefault(_nextTick); | ||
var _boundary = require("./util/boundary"); | ||
var _boundary2 = _interopRequireDefault(_boundary); | ||
var _isString = require("./util/isString"); | ||
var _isString2 = _interopRequireDefault(_isString); | ||
var _isBuffer = require("./util/isBuffer"); | ||
@@ -59,10 +75,2 @@ | ||
var _nextTick = require("./util/nextTick"); | ||
var _nextTick2 = _interopRequireDefault(_nextTick); | ||
var _boundary = require("./util/boundary"); | ||
var _boundary2 = _interopRequireDefault(_boundary); | ||
var _StreamIterator = require("./util/StreamIterator"); | ||
@@ -74,6 +82,2 @@ | ||
const isString = val => typeof val === "string"; | ||
const isArray = Array.isArray; | ||
let FormData = class FormData { | ||
@@ -91,5 +95,5 @@ constructor() { | ||
const ch = curr.value; | ||
const chunk = curr.value; | ||
this.__stream.push(ch); | ||
this.__stream.push((0, _isBuffer2.default)(chunk) ? chunk : Buffer.from(String(chunk))); | ||
}; | ||
@@ -102,2 +106,4 @@ | ||
this.append = (name, value, filename) => this.__setField(name, value, filename, 1); | ||
this.set = (name, value, filename) => this.__setField(name, value, filename); | ||
@@ -112,5 +118,25 @@ | ||
// I should add this behaviour somehow | ||
return field ? field.value : void 0; | ||
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); | ||
@@ -126,4 +152,10 @@ | ||
(0, _bind2.default)([_iterator3.default, _symbol2.default.asyncIterator, "toString", "toJSON", "inspect", "keys", "values", "entries"], 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); | ||
this.__carriage = "\r\n"; | ||
@@ -143,6 +175,14 @@ this.__defaultContentType = "application/octet-steam"; | ||
this.__stream = new _stream.Readable({ read }); | ||
} | ||
this.headers = { | ||
"Content-Type": (0, _concat2.default)("multipart/form-data; boundary=", this.__boundary) | ||
}; | ||
/** | ||
* Check if given value is instance of FormData | ||
* Note: This method is not a part of client-side FormData interface. | ||
* | ||
* @param {any} value | ||
* | ||
* @return {boolean} | ||
*/ | ||
static isFormData(value) { | ||
return value instanceof FormData; | ||
} | ||
@@ -181,38 +221,15 @@ | ||
const [name, { value, filename }] = curr.value; | ||
const [name, { values, filename }] = curr.value; | ||
yield _this.__getHeader(name, filename); | ||
if ((0, _isReadable2.default)(value)) { | ||
const iterator = new _StreamIterator2.default(value); | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = (0, _asyncIterator3.default)(iterator), _step, _value; _step = yield _asyncGenerator3.default.await(_iterator.next()), _iteratorNormalCompletion = _step.done, _value = yield _asyncGenerator3.default.await(_step.value), !_iteratorNormalCompletion; _iteratorNormalCompletion = true) { | ||
const ch = _value; | ||
yield ch; | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
yield _asyncGenerator3.default.await(_iterator.return()); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
for (const value of values) { | ||
if ((0, _isReadable2.default)(value)) { | ||
yield* (0, _asyncGeneratorDelegate3.default)((0, _asyncIterator3.default)(new _StreamIterator2.default(value)), _asyncGenerator3.default.await); // Read the stream contents | ||
} else { | ||
yield value; | ||
} | ||
} else { | ||
yield (0, _isBuffer2.default)(value) ? value : Buffer.from(value); | ||
} | ||
yield Buffer.from(_this.__carriage); | ||
yield _this.__carriage; | ||
} | ||
@@ -223,3 +240,7 @@ })(); | ||
/** | ||
* Read values from internal storage and push it to the internal stream | ||
* | ||
* @private | ||
* | ||
* @return {void} | ||
*/ | ||
@@ -239,7 +260,7 @@ | ||
__setField(name, value, filename, append = false) { | ||
(0, _invariant2.default)(!isString(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", typeof name); | ||
(0, _invariant2.default)(filename && !isString(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", typeof filename); | ||
// Try to get a filename for buffer and stream values | ||
// Try to get a filename for buffer and Readable values | ||
if ((0, _isBuffer2.default)(value) && filename) { | ||
@@ -251,12 +272,32 @@ filename = (0, _path.basename)(filename); | ||
// Convers value to a string if it not stream or buffer | ||
if (!(0, _isBuffer2.default)(value) && !(0, _isReadable2.default)(value)) { | ||
value = String(value); | ||
append = Boolean(append); | ||
const field = this.__contents.get(name); | ||
// Set a new field | ||
if (!field) { | ||
return void this.__contents.set(name, { append, filename, values: [value] }); | ||
} | ||
append = Boolean(append); | ||
// Replace a value of the existing field if "set" called | ||
if (!append) { | ||
return void this.__contents.set(name, { append, filename, values: [value] }); | ||
} | ||
this.__contents.set(String(name), { append, value, filename }); | ||
// Do nothing if the field has been created from .set() | ||
if (!field.append) { | ||
return; | ||
} | ||
// Append a new value to the existing field | ||
field.values.push(value); | ||
this.__contents.set(name, field); | ||
} | ||
/** | ||
* Returns boundary string | ||
* | ||
* @return {string} | ||
*/ | ||
get boundary() { | ||
@@ -266,14 +307,11 @@ return this.__boundary; | ||
// append = (name, value, filename) => { | ||
// if (this.has(name) === false) { | ||
// return this.__setField(name, value, filename, true) | ||
// } | ||
/** | ||
* Returns the internal stream | ||
* | ||
* @return {stream.Readable} | ||
*/ | ||
get stream() { | ||
return this.__stream; | ||
} | ||
// const field = this.get(name) | ||
// if (field.append === true) { | ||
// this.__setField(name, `${field.value}${value}`, filename) | ||
// } | ||
// } | ||
/** | ||
@@ -299,5 +337,2 @@ * Set new field on FormData | ||
// TODO: Implement this method due to spec | ||
// getAll = () => {} | ||
toString() { | ||
@@ -322,8 +357,6 @@ return `[object ${this.constructor.name}]`; | ||
*values() { | ||
for (let value of this.__contents.values()) { | ||
if (typeof value !== "object" || isArray(value)) { | ||
value = String(value); | ||
} | ||
for (const name of this.keys()) { | ||
const value = this.getAll(name); | ||
yield value; | ||
yield value.length === 1 ? value[0] : value; | ||
} | ||
@@ -333,15 +366,19 @@ } | ||
*entries() { | ||
for (const [name, value] of this.__contents) { | ||
if (typeof value === "object" && value != null || !isArray(value)) { | ||
yield [name, value]; | ||
} else { | ||
yield [name, String(value)]; | ||
} | ||
for (const name of this.keys()) { | ||
const value = this.getAll(name); | ||
yield [name, value.length === 1 ? value[0] : value]; | ||
} | ||
} | ||
[_iterator3.default]() { | ||
[_iterator2.default]() { | ||
return this.entries(); | ||
} | ||
/** | ||
* This method allows to read a content from internal stream | ||
* using async generators and for-await..of APIs | ||
* | ||
* @return {StreamIterator} | ||
*/ | ||
[_symbol2.default.asyncIterator]() { | ||
@@ -348,0 +385,0 @@ return new _StreamIterator2.default(this.__stream); |
{ | ||
"name": "formdata-node", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "FormData implementation for Node.js. Built over Readable stream and async generators.", | ||
"repository": "octet-stream/node-formdata", | ||
"repository": "octet-stream/form-data", | ||
"author": "Nick K. <nick.kruchinin@gmail.com>", | ||
@@ -7,0 +7,0 @@ "license": "MIT", |
@@ -43,2 +43,13 @@ # FormData | ||
##### `append(name, value[, filename]) -> {void}` | ||
Appends a new value onto an existing key inside a FormData object, | ||
or adds the key if it does not already exist. | ||
- **{string}** name – The name of the field whose data is contained in **value** | ||
- **{any}** value – The field value. You can pass any JavaScript primitive type (including **null** and **undefined**), | ||
**[Buffer](https://nodejs.org/api/buffer.html#buffer_buffer)** or **[Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable)** stream. | ||
Note that Arrays and Object will be converted to **string** by using **String** function. | ||
- **{string}** [filename = undefined] – A filename of given field. Can be added only for **Buffer** and **Readable** . | ||
##### `get(name) -> {string | Buffer | stream.Readable}` | ||
@@ -51,2 +62,8 @@ | ||
##### `getAll(name) -> {string[] | Buffer[] | stream.Readable[]}` | ||
Returns all the values associated with a given key from within a **FormData** object. | ||
- **{string}** – A name of the value you want to retrieve. | ||
##### `has(name) -> {boolean}` | ||
@@ -78,2 +95,8 @@ | ||
An alias of [entries](#entries---iterator) | ||
An alias of [FormData#entries](#entries---iterator) | ||
## Related packages | ||
- [then-busboy](https://github.com/octet-stream/then-busboy) – Promise-based wrapper around Busboy. | ||
Process multipart/form-data content and returns it as a single object. | ||
Will be helpful to handle your data on the server-side applications. |
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
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
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
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
23596
15
458
100