Note that SuperAgent expects the global Promise
object to be present. You'll need to use v7 and a polyfill to use promises in Internet Explorer or Node.js 0.10.
We have dropped support in v8 for IE. You must add a polyfill for WeakRef and BigInt if you wish to support Opera 85, iOS Safari 12.2-12.5, for example using https://polyfill.io:
-<script src="https://polyfill.io/v3/polyfill.min.js?features=WeakRef,BigInt"></script>
+We have dropped support in v8 for IE. You must add a polyfill for WeakRef and BigInt if you wish to support Opera 85, iOS Safari 12.2-12.5, for example using https://cdnjs.cloudflare.com/polyfill/:
+<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=WeakRef,BigInt"></script>
Browser and node versions
SuperAgent has two implementations: one for web browsers (using XHR) and one for Node.JS (using core http module). By default Browserify and WebPack will pick the browser version.
diff --git a/package.json b/package.json
index 8ea210016..9a2fdb4d6 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "superagent",
"description": "elegant & feature rich browser / node HTTP with a fluent API",
- "version": "8.1.2",
+ "version": "9.0.0",
"author": "TJ Holowaychuk ",
"browser": {
"./src/node/index.js": "./src/client.js",
@@ -24,7 +24,7 @@
"debug": "^4.3.4",
"fast-safe-stringify": "^2.1.1",
"form-data": "^4.0.0",
- "formidable": "^2.1.2",
+ "formidable": "^3.5.1",
"methods": "^1.1.2",
"mime": "2.6.0",
"qs": "^6.11.0",
@@ -38,8 +38,8 @@
"@babel/runtime": "^7.20.13",
"@commitlint/cli": "17",
"@commitlint/config-conventional": "17",
- "Base64": "^1.1.0",
"babelify": "^10.0.0",
+ "Base64": "^1.1.0",
"basic-auth-connect": "^1.0.0",
"body-parser": "^1.20.1",
"browserify": "^17.0.0",
@@ -69,7 +69,7 @@
"zuul": "^3.12.0"
},
"engines": {
- "node": ">=6.4.0 <13 || >=14"
+ "node": ">=14.18.0"
},
"files": [
"dist/*.js",
diff --git a/src/node/index.js b/src/node/index.js
index e6dc73cc9..780b4f53a 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -469,7 +469,6 @@ Request.prototype._pipeContinue = function (stream, options) {
res.pipe(stream, options);
res.once('end', () => this.emit('end'));
}
-
});
return stream;
};
@@ -1093,7 +1092,7 @@ Request.prototype._end = function () {
parser = exports.parse.image; // It's actually a generic Buffer
buffer = true;
} else if (multipart) {
- const form = formidable();
+ const form = formidable.formidable();
parser = form.parse.bind(form);
buffer = true;
} else if (isBinary(mime)) {
@@ -1125,7 +1124,7 @@ Request.prototype._end = function () {
let parserHandlesEnd = false;
if (buffer) {
// Protectiona against zip bombs and other nuisance
- let responseBytesLeft = this._maxResponseSize || 200_000_000;
+ let responseBytesLeft = this._maxResponseSize || 200000000;
res.on('data', (buf) => {
responseBytesLeft -= buf.byteLength || buf.length > 0 ? buf.length : 0;
if (responseBytesLeft < 0) {
@@ -1162,6 +1161,31 @@ Request.prototype._end = function () {
}
if (parserHandlesEnd) {
+ if (multipart) {
+ // formidable v3 always returns an array with the value in it
+ // so we need to flatten it
+ if (object) {
+ for (const key in object) {
+ const value = object[key];
+ if (Array.isArray(value) && value.length === 1) {
+ object[key] = value[0];
+ } else {
+ object[key] = value;
+ }
+ }
+ }
+
+ if (files) {
+ for (const key in files) {
+ const value = files[key];
+ if (Array.isArray(value) && value.length === 1) {
+ files[key] = value[0];
+ } else {
+ files[key] = value;
+ }
+ }
+ }
+ }
this.emit('end');
this.callback(null, this._emitResponse(object, files));
}