superagent 3.8.1 → 4.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.yml +5 -2
- package/.zuul.yml +5 -2
- package/History.md +35 -0
- package/Makefile +10 -1
- package/Readme.md +10 -6
- package/docs/index.md +133 -69
- package/docs/test.html +6 -6
- package/dump.js +1 -0
- package/lib/agent-base.js +5 -5
- package/lib/client.js +80 -79
- package/lib/node/http2wrapper.js +188 -0
- package/lib/node/index.js +189 -52
- package/lib/node/parsers/text.js +1 -1
- package/lib/node/parsers/urlencoded.js +1 -1
- package/lib/node/response.js +1 -1
- package/lib/node/unzip.js +2 -2
- package/lib/request-base.js +29 -28
- package/lib/response-base.js +8 -6
- package/lib/utils.js +16 -22
- package/package.json +18 -15
- package/superagent.js +231 -209
- package/test.js +7 -0
- package/yarn.lock +1774 -1080
package/lib/request-base.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Module of mixed-in functions shared between node and client code
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
const isObject = require('./is-object');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Expose `RequestBase`.
|
|
@@ -30,7 +30,7 @@ function RequestBase(obj) {
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
function mixin(obj) {
|
|
33
|
-
for (
|
|
33
|
+
for (const key in RequestBase.prototype) {
|
|
34
34
|
obj[key] = RequestBase.prototype[key];
|
|
35
35
|
}
|
|
36
36
|
return obj;
|
|
@@ -122,7 +122,7 @@ RequestBase.prototype.timeout = function timeout(options){
|
|
|
122
122
|
return this;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
for(
|
|
125
|
+
for(const option in options) {
|
|
126
126
|
switch(option) {
|
|
127
127
|
case 'deadline':
|
|
128
128
|
this._timeout = options.deadline;
|
|
@@ -158,7 +158,7 @@ RequestBase.prototype.retry = function retry(count, fn){
|
|
|
158
158
|
return this;
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
const ERROR_CODES = [
|
|
162
162
|
'ECONNRESET',
|
|
163
163
|
'ETIMEDOUT',
|
|
164
164
|
'EADDRINFO',
|
|
@@ -179,7 +179,7 @@ RequestBase.prototype._shouldRetry = function(err, res) {
|
|
|
179
179
|
}
|
|
180
180
|
if (this._retryCallback) {
|
|
181
181
|
try {
|
|
182
|
-
|
|
182
|
+
const override = this._retryCallback(err, res);
|
|
183
183
|
if (override === true) return true;
|
|
184
184
|
if (override === false) return false;
|
|
185
185
|
// undefined falls back to defaults
|
|
@@ -230,12 +230,13 @@ RequestBase.prototype._retry = function() {
|
|
|
230
230
|
|
|
231
231
|
RequestBase.prototype.then = function then(resolve, reject) {
|
|
232
232
|
if (!this._fullfilledPromise) {
|
|
233
|
-
|
|
233
|
+
const self = this;
|
|
234
234
|
if (this._endCalled) {
|
|
235
235
|
console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises");
|
|
236
236
|
}
|
|
237
|
-
this._fullfilledPromise = new Promise(
|
|
238
|
-
self.
|
|
237
|
+
this._fullfilledPromise = new Promise((innerResolve, innerReject) => {
|
|
238
|
+
self.on('error', innerReject);
|
|
239
|
+
self.end((err, res) => {
|
|
239
240
|
if (err) innerReject(err);
|
|
240
241
|
else innerResolve(res);
|
|
241
242
|
});
|
|
@@ -244,7 +245,7 @@ RequestBase.prototype.then = function then(resolve, reject) {
|
|
|
244
245
|
return this._fullfilledPromise.then(resolve, reject);
|
|
245
246
|
};
|
|
246
247
|
|
|
247
|
-
RequestBase.prototype
|
|
248
|
+
RequestBase.prototype['catch'] = function(cb) {
|
|
248
249
|
return this.then(undefined, cb);
|
|
249
250
|
};
|
|
250
251
|
|
|
@@ -325,7 +326,7 @@ RequestBase.prototype.getHeader = RequestBase.prototype.get;
|
|
|
325
326
|
|
|
326
327
|
RequestBase.prototype.set = function(field, val){
|
|
327
328
|
if (isObject(field)) {
|
|
328
|
-
for (
|
|
329
|
+
for (const key in field) {
|
|
329
330
|
this.set(key, field[key]);
|
|
330
331
|
}
|
|
331
332
|
return this;
|
|
@@ -379,18 +380,18 @@ RequestBase.prototype.field = function(name, val) {
|
|
|
379
380
|
}
|
|
380
381
|
|
|
381
382
|
if (this._data) {
|
|
382
|
-
|
|
383
|
+
throw new Error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
|
|
383
384
|
}
|
|
384
385
|
|
|
385
386
|
if (isObject(name)) {
|
|
386
|
-
for (
|
|
387
|
+
for (const key in name) {
|
|
387
388
|
this.field(key, name[key]);
|
|
388
389
|
}
|
|
389
390
|
return this;
|
|
390
391
|
}
|
|
391
392
|
|
|
392
393
|
if (Array.isArray(val)) {
|
|
393
|
-
for (
|
|
394
|
+
for (const i in val) {
|
|
394
395
|
this.field(name, val[i]);
|
|
395
396
|
}
|
|
396
397
|
return this;
|
|
@@ -428,7 +429,7 @@ RequestBase.prototype.abort = function(){
|
|
|
428
429
|
RequestBase.prototype._auth = function(user, pass, options, base64Encoder) {
|
|
429
430
|
switch (options.type) {
|
|
430
431
|
case 'basic':
|
|
431
|
-
this.set('Authorization',
|
|
432
|
+
this.set('Authorization', `Basic ${base64Encoder(`${user}:${pass}`)}`);
|
|
432
433
|
break;
|
|
433
434
|
|
|
434
435
|
case 'auto':
|
|
@@ -437,7 +438,7 @@ RequestBase.prototype._auth = function(user, pass, options, base64Encoder) {
|
|
|
437
438
|
break;
|
|
438
439
|
|
|
439
440
|
case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
|
|
440
|
-
this.set('Authorization',
|
|
441
|
+
this.set('Authorization', `Bearer ${user}`);
|
|
441
442
|
break;
|
|
442
443
|
}
|
|
443
444
|
return this;
|
|
@@ -548,11 +549,11 @@ RequestBase.prototype.toJSON = function() {
|
|
|
548
549
|
*/
|
|
549
550
|
|
|
550
551
|
RequestBase.prototype.send = function(data){
|
|
551
|
-
|
|
552
|
-
|
|
552
|
+
const isObj = isObject(data);
|
|
553
|
+
let type = this._header['content-type'];
|
|
553
554
|
|
|
554
555
|
if (this._formData) {
|
|
555
|
-
|
|
556
|
+
throw new Error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
|
|
556
557
|
}
|
|
557
558
|
|
|
558
559
|
if (isObj && !this._data) {
|
|
@@ -567,7 +568,7 @@ RequestBase.prototype.send = function(data){
|
|
|
567
568
|
|
|
568
569
|
// merge
|
|
569
570
|
if (isObj && isObject(this._data)) {
|
|
570
|
-
for (
|
|
571
|
+
for (const key in data) {
|
|
571
572
|
this._data[key] = data[key];
|
|
572
573
|
}
|
|
573
574
|
} else if ('string' == typeof data) {
|
|
@@ -576,7 +577,7 @@ RequestBase.prototype.send = function(data){
|
|
|
576
577
|
type = this._header['content-type'];
|
|
577
578
|
if ('application/x-www-form-urlencoded' == type) {
|
|
578
579
|
this._data = this._data
|
|
579
|
-
? this._data
|
|
580
|
+
? `${this._data}&${data}`
|
|
580
581
|
: data;
|
|
581
582
|
} else {
|
|
582
583
|
this._data = (this._data || '') + data;
|
|
@@ -634,16 +635,16 @@ RequestBase.prototype.sortQuery = function(sort) {
|
|
|
634
635
|
* @api private
|
|
635
636
|
*/
|
|
636
637
|
RequestBase.prototype._finalizeQueryString = function(){
|
|
637
|
-
|
|
638
|
+
const query = this._query.join('&');
|
|
638
639
|
if (query) {
|
|
639
640
|
this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
|
|
640
641
|
}
|
|
641
642
|
this._query.length = 0; // Makes the call idempotent
|
|
642
643
|
|
|
643
644
|
if (this._sort) {
|
|
644
|
-
|
|
645
|
+
const index = this.url.indexOf('?');
|
|
645
646
|
if (index >= 0) {
|
|
646
|
-
|
|
647
|
+
const queryArr = this.url.substring(index + 1).split('&');
|
|
647
648
|
if ('function' === typeof this._sort) {
|
|
648
649
|
queryArr.sort(this._sort);
|
|
649
650
|
} else {
|
|
@@ -655,7 +656,7 @@ RequestBase.prototype._finalizeQueryString = function(){
|
|
|
655
656
|
};
|
|
656
657
|
|
|
657
658
|
// For backwards compat only
|
|
658
|
-
RequestBase.prototype._appendQueryString =
|
|
659
|
+
RequestBase.prototype._appendQueryString = () => {console.trace("Unsupported");}
|
|
659
660
|
|
|
660
661
|
/**
|
|
661
662
|
* Invoke callback with timeout error.
|
|
@@ -667,7 +668,7 @@ RequestBase.prototype._timeoutError = function(reason, timeout, errno){
|
|
|
667
668
|
if (this._aborted) {
|
|
668
669
|
return;
|
|
669
670
|
}
|
|
670
|
-
|
|
671
|
+
const err = new Error(`${reason + timeout}ms exceeded`);
|
|
671
672
|
err.timeout = timeout;
|
|
672
673
|
err.code = 'ECONNABORTED';
|
|
673
674
|
err.errno = errno;
|
|
@@ -677,17 +678,17 @@ RequestBase.prototype._timeoutError = function(reason, timeout, errno){
|
|
|
677
678
|
};
|
|
678
679
|
|
|
679
680
|
RequestBase.prototype._setTimeouts = function() {
|
|
680
|
-
|
|
681
|
+
const self = this;
|
|
681
682
|
|
|
682
683
|
// deadline
|
|
683
684
|
if (this._timeout && !this._timer) {
|
|
684
|
-
this._timer = setTimeout(
|
|
685
|
+
this._timer = setTimeout(() => {
|
|
685
686
|
self._timeoutError('Timeout of ', self._timeout, 'ETIME');
|
|
686
687
|
}, this._timeout);
|
|
687
688
|
}
|
|
688
689
|
// response timeout
|
|
689
690
|
if (this._responseTimeout && !this._responseTimeoutTimer) {
|
|
690
|
-
this._responseTimeoutTimer = setTimeout(
|
|
691
|
+
this._responseTimeoutTimer = setTimeout(() => {
|
|
691
692
|
self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
|
|
692
693
|
}, this._responseTimeout);
|
|
693
694
|
}
|
package/lib/response-base.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Module dependencies.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const utils = require('./utils');
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Expose `ResponseBase`.
|
|
@@ -31,7 +31,7 @@ function ResponseBase(obj) {
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
function mixin(obj) {
|
|
34
|
-
for (
|
|
34
|
+
for (const key in ResponseBase.prototype) {
|
|
35
35
|
obj[key] = ResponseBase.prototype[key];
|
|
36
36
|
}
|
|
37
37
|
return obj;
|
|
@@ -66,12 +66,12 @@ ResponseBase.prototype._setHeaderProperties = function(header){
|
|
|
66
66
|
// TODO: make this a util
|
|
67
67
|
|
|
68
68
|
// content-type
|
|
69
|
-
|
|
69
|
+
const ct = header['content-type'] || '';
|
|
70
70
|
this.type = utils.type(ct);
|
|
71
71
|
|
|
72
72
|
// params
|
|
73
|
-
|
|
74
|
-
for (
|
|
73
|
+
const params = utils.params(ct);
|
|
74
|
+
for (const key in params) this[key] = params[key];
|
|
75
75
|
|
|
76
76
|
this.links = {};
|
|
77
77
|
|
|
@@ -107,7 +107,7 @@ ResponseBase.prototype._setHeaderProperties = function(header){
|
|
|
107
107
|
*/
|
|
108
108
|
|
|
109
109
|
ResponseBase.prototype._setStatusProperties = function(status){
|
|
110
|
-
|
|
110
|
+
const type = status / 100 | 0;
|
|
111
111
|
|
|
112
112
|
// status / class
|
|
113
113
|
this.status = this.statusCode = status;
|
|
@@ -124,6 +124,7 @@ ResponseBase.prototype._setStatusProperties = function(status){
|
|
|
124
124
|
: false;
|
|
125
125
|
|
|
126
126
|
// sugar
|
|
127
|
+
this.created = 201 == status;
|
|
127
128
|
this.accepted = 202 == status;
|
|
128
129
|
this.noContent = 204 == status;
|
|
129
130
|
this.badRequest = 400 == status;
|
|
@@ -131,4 +132,5 @@ ResponseBase.prototype._setStatusProperties = function(status){
|
|
|
131
132
|
this.notAcceptable = 406 == status;
|
|
132
133
|
this.forbidden = 403 == status;
|
|
133
134
|
this.notFound = 404 == status;
|
|
135
|
+
this.unprocessableEntity = 422 == status;
|
|
134
136
|
};
|
package/lib/utils.js
CHANGED
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
* @api private
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
exports.type =
|
|
12
|
-
return str.split(/ *; */).shift();
|
|
13
|
-
};
|
|
11
|
+
exports.type = str => str.split(/ *; */).shift();
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Return header field parameters.
|
|
@@ -20,16 +18,14 @@ exports.type = function(str){
|
|
|
20
18
|
* @api private
|
|
21
19
|
*/
|
|
22
20
|
|
|
23
|
-
exports.params =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var val = parts.shift();
|
|
21
|
+
exports.params = str => str.split(/ *; */).reduce((obj, str) => {
|
|
22
|
+
const parts = str.split(/ *= */);
|
|
23
|
+
const key = parts.shift();
|
|
24
|
+
const val = parts.shift();
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
26
|
+
if (key && val) obj[key] = val;
|
|
27
|
+
return obj;
|
|
28
|
+
}, {});
|
|
33
29
|
|
|
34
30
|
/**
|
|
35
31
|
* Parse Link header fields.
|
|
@@ -39,15 +35,13 @@ exports.params = function(str){
|
|
|
39
35
|
* @api private
|
|
40
36
|
*/
|
|
41
37
|
|
|
42
|
-
exports.parseLinks =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}, {});
|
|
50
|
-
};
|
|
38
|
+
exports.parseLinks = str => str.split(/ *, */).reduce((obj, str) => {
|
|
39
|
+
const parts = str.split(/ *; */);
|
|
40
|
+
const url = parts[0].slice(1, -1);
|
|
41
|
+
const rel = parts[1].split(/ *= */)[1].slice(1, -1);
|
|
42
|
+
obj[rel] = url;
|
|
43
|
+
return obj;
|
|
44
|
+
}, {});
|
|
51
45
|
|
|
52
46
|
/**
|
|
53
47
|
* Strip content related fields from `header`.
|
|
@@ -57,7 +51,7 @@ exports.parseLinks = function(str){
|
|
|
57
51
|
* @api private
|
|
58
52
|
*/
|
|
59
53
|
|
|
60
|
-
exports.cleanHeader =
|
|
54
|
+
exports.cleanHeader = (header, changesOrigin) => {
|
|
61
55
|
delete header['content-type'];
|
|
62
56
|
delete header['content-length'];
|
|
63
57
|
delete header['transfer-encoding'];
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superagent",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-beta.5",
|
|
4
4
|
"description": "elegant & feature rich browser / node HTTP with a fluent API",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepare": "make all",
|
|
7
|
-
"test": "make test"
|
|
7
|
+
"test": "make test",
|
|
8
|
+
"test-http2": "make test-node-http2"
|
|
8
9
|
},
|
|
9
10
|
"keywords": [
|
|
10
11
|
"http",
|
|
@@ -25,30 +26,32 @@
|
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
28
|
"component-emitter": "^1.2.0",
|
|
28
|
-
"cookiejar": "^2.1.
|
|
29
|
-
"debug": "^
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"formidable": "^1.1.1",
|
|
29
|
+
"cookiejar": "^2.1.2",
|
|
30
|
+
"debug": "^4.0.0",
|
|
31
|
+
"form-data": "^2.3.2",
|
|
32
|
+
"formidable": "^1.2.0",
|
|
33
33
|
"methods": "^1.1.1",
|
|
34
|
-
"mime": "^
|
|
34
|
+
"mime": "^2.0.3",
|
|
35
35
|
"qs": "^6.5.1",
|
|
36
|
-
"readable-stream": "^
|
|
36
|
+
"readable-stream": "^3.0.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"Base64": "^1.0.1",
|
|
40
|
+
"babel-core": "^6.26.3",
|
|
41
|
+
"babel-preset-es2015": "^6.24.1",
|
|
42
|
+
"babelify": "^8.0.0",
|
|
40
43
|
"basic-auth-connect": "^1.0.0",
|
|
41
44
|
"body-parser": "^1.18.2",
|
|
42
|
-
"browserify": "^
|
|
45
|
+
"browserify": "^16.2.0",
|
|
43
46
|
"cookie-parser": "^1.4.3",
|
|
44
|
-
"express": "^4.16.
|
|
47
|
+
"express": "^4.16.3",
|
|
45
48
|
"express-session": "^1.15.6",
|
|
46
|
-
"marked": "^0.
|
|
49
|
+
"marked": "^0.5.0",
|
|
47
50
|
"mocha": "^3.5.3",
|
|
48
51
|
"multer": "^1.3.0",
|
|
49
|
-
"should": "^
|
|
52
|
+
"should": "^13.2.0",
|
|
50
53
|
"should-http": "^0.1.1",
|
|
51
|
-
"zuul": "^3.
|
|
54
|
+
"zuul": "^3.12.0"
|
|
52
55
|
},
|
|
53
56
|
"browser": {
|
|
54
57
|
"./lib/node/index.js": "./lib/client.js",
|
|
@@ -61,6 +64,6 @@
|
|
|
61
64
|
},
|
|
62
65
|
"main": "./lib/node/index.js",
|
|
63
66
|
"engines": {
|
|
64
|
-
"node": ">=
|
|
67
|
+
"node": ">= 6.0"
|
|
65
68
|
}
|
|
66
69
|
}
|