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 CHANGED
@@ -1,9 +1,9 @@
1
1
  sudo: false
2
2
  language: node_js
3
3
  node_js:
4
+ - "10"
4
5
  - "8"
5
6
  - "6"
6
- - "4"
7
7
 
8
8
  env:
9
9
  global:
@@ -12,5 +12,8 @@ env:
12
12
 
13
13
  matrix:
14
14
  include:
15
- - node_js: "8"
15
+ - node_js: "9"
16
16
  env: BROWSER=1
17
+ include:
18
+ - node_js: "10"
19
+ env: HTTP2_TEST=1
package/.zuul.yml CHANGED
@@ -8,7 +8,10 @@ browsers:
8
8
  version: latest
9
9
  - name: safari
10
10
  version: latest
11
- - name: iphone
12
- version: latest
13
11
  - name: ie
14
12
  version: 9..latest
13
+ browserify:
14
+ - transform:
15
+ name: babelify
16
+ presets:
17
+ - [ babel-preset-es2015, { loose: true } ]
package/History.md CHANGED
@@ -1,3 +1,38 @@
1
+ # 4.0.0
2
+
3
+ ## Breaking changes
4
+
5
+ * Node.js v4 has reached it's end of life, so we no longer support it. It's v6+ or later. We recommend Node.js 10.
6
+ * We now use ES6 in the browser code, too.
7
+ * If you're using Browserify or Webpack to package code for Internet Explorer, you will also have to use Babel.
8
+ * The pre-built node_modules/superagent.js is still ES5-compatible.
9
+ * `.end(…)` returns `undefined` instead of the request. If you need the request object after calling `.end()` (and you probably don't), save it in a variable and call `request.end(…)`. Consider not using `.end()` at all, and migrating to promises by calling `.then()` instead.
10
+ * In Node, responses with unknown MIME type are buffered by default. To get old behavior, if you use custom *unbuffered* parsers, add `.buffer(false)` to requests or set `superagent.buffer[yourMimeType] = false`.
11
+ * Invalid uses of `.pipe()` throw.
12
+
13
+ ## Minor changes
14
+
15
+ * Throw if `req.abort().end()` is called
16
+ * Throw if using unsupported mix of send and field
17
+ * Reject `.end()` promise on all error events (Kornel Lesiński)
18
+ * Set `https.servername` from the `Host` header (Kornel Lesiński)
19
+ * Leave backticks unencoded in query strings where possible (Ethan Resnick)
20
+ * Update node-mime to 2.x (Alexey Kucherenko)
21
+ * Allow default buffer settings based on response-type (shrey)
22
+ * `response.buffered` is more accurate.
23
+
24
+ # 3.8.3 (2018-04-29)
25
+
26
+ * Add flags for 201 & 422 responses (Nikhil Fadnis)
27
+ * Emit progress event while uploading Node `Buffer` via send method (Sergey Akhalkov)
28
+ * Fixed setting correct cookies for redirects (Damien Clark)
29
+ * Replace .catch with ['catch'] for IE9 Support (Miguel Stevens)
30
+
31
+ # 3.8.2 (2017-12-09)
32
+
33
+ * Fixed handling of exceptions thrown from callbacks
34
+ * Stricter matching of `+json` MIME types.
35
+
1
36
  # 3.8.1 (2017-11-08)
2
37
 
3
38
  * Clear authorization header on cross-domain redirect
package/Makefile CHANGED
@@ -11,9 +11,17 @@ test:
11
11
  test-node:
12
12
  @NODE_ENV=test NODE_TLS_REJECT_UNAUTHORIZED=0 ./node_modules/.bin/mocha \
13
13
  --require should \
14
+ --trace-warnings \
15
+ --reporter $(REPORTER) \
16
+ --timeout 5000 \
17
+ $(NODETESTS)
18
+
19
+ test-node-http2:
20
+ @NODE_ENV=test HTTP2_TEST=1 NODE_TLS_REJECT_UNAUTHORIZED=0 node ./node_modules/.bin/mocha \
21
+ --require should \
22
+ --trace-warnings \
14
23
  --reporter $(REPORTER) \
15
24
  --timeout 5000 \
16
- --growl \
17
25
  $(NODETESTS)
18
26
 
19
27
  test-cov: lib-cov
@@ -30,6 +38,7 @@ lib-cov:
30
38
 
31
39
  superagent.js: lib/node/*.js lib/node/parsers/*.js
32
40
  @./node_modules/.bin/browserify \
41
+ -t [ babelify --presets [ "babel-preset-es2015" --loose true ] ] \
33
42
  --standalone superagent \
34
43
  --outfile superagent.js .
35
44
 
package/Readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Sauce Test Status](https://saucelabs.com/browser-matrix/shtylman-superagent.svg)](https://saucelabs.com/u/shtylman-superagent)
4
4
 
5
- SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.io/superagent/).
5
+ SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](https://visionmedia.github.io/superagent/).
6
6
 
7
7
  ![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png)
8
8
 
@@ -35,7 +35,7 @@ Tested browsers:
35
35
  - Latest Android, iPhone
36
36
  - IE10 through latest. IE9 with polyfills. Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`.
37
37
 
38
- Node 4 or later is required.
38
+ Node 6 or later is required.
39
39
 
40
40
  ## Plugins
41
41
 
@@ -63,13 +63,13 @@ Existing plugins:
63
63
  * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL
64
64
  * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API
65
65
  * [superagent-cache](https://github.com/jpodwys/superagent-cache) - A global SuperAgent patch with built-in, flexible caching
66
- * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching
66
+ * [superagent-cache-plugin](https://github.com/jpodwys/superagent-cache-plugin) - A SuperAgent plugin with built-in, flexible caching
67
67
  * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent
68
68
  * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases
69
- * [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests.
70
69
  * [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax
71
70
  * [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests
72
71
  * [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's SuperAgent
72
+ * [superagent-verbose-errors](https://github.com/jcoreio/superagent-verbose-errors) - include response body in error messages for failed requests
73
73
 
74
74
  Please prefix your plugin with `superagent-*` so that it can easily be found by others.
75
75
 
@@ -79,15 +79,19 @@ For SuperAgent extensions such as couchdb and oauth visit the [wiki](https://git
79
79
 
80
80
  Our breaking changes are mostly in rarely used functionality and from stricter error handling.
81
81
 
82
+ * [3.x to 4.x](https://github.com/visionmedia/superagent/releases/tag/v4.0.0-alpha.1):
83
+ - Ensure you're running Node 6 or later. We've dropped support for Node 4.
84
+ - We've started using ES6 and for compatibility with Internet Explorer you may need to use Babel.
85
+ - We suggest migrating from `.end()` callbacks to `.then()` or `await`.
82
86
  * [2.x to 3.x](https://github.com/visionmedia/superagent/releases/tag/v3.0.0):
83
- - Ensure you're running Node 4 or later. We dropped support for Node 0.x.
87
+ - Ensure you're running Node 4 or later. We've dropped support for Node 0.x.
84
88
  - Test code that calls `.send()` multiple times. Invalid calls to `.send()` will now throw instead of sending garbage.
85
89
  * [1.x to 2.x](https://github.com/visionmedia/superagent/releases/tag/v2.0.0):
86
90
  - If you use `.parse()` in the *browser* version, rename it to `.serialize()`.
87
91
  - If you rely on `undefined` in query-string values being sent literally as the text "undefined", switch to checking for missing value instead. `?key=undefined` is now `?key` (without a value).
88
92
  - If you use `.then()` in Internet Explorer, ensure that you have a polyfill that adds a global `Promise` object.
89
93
  * 0.x to 1.x:
90
- - Use `.end(function(err, res){})`. 1-argument version is no longer supported.
94
+ - Instead of 1-argument callback `.end(function(res){})` use `.then(res => {})`.
91
95
 
92
96
  ## Running node tests
93
97
 
package/docs/index.md CHANGED
@@ -8,51 +8,52 @@ SuperAgent is light-weight progressive ajax API crafted for flexibility, readabi
8
8
  .send({ name: 'Manny', species: 'cat' })
9
9
  .set('X-API-Key', 'foobar')
10
10
  .set('Accept', 'application/json')
11
- .end(function(err, res){
12
- if (err || !res.ok) {
13
- alert('Oh no! error');
14
- } else {
15
- alert('yay got ' + JSON.stringify(res.body));
16
- }
11
+ .then(res => {
12
+ alert('yay got ' + JSON.stringify(res.body));
17
13
  });
18
14
 
19
15
  ## Test documentation
20
16
 
21
- The following [test documentation](docs/test.html) was generated with [Mocha's](http://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation.
17
+ The following [test documentation](docs/test.html) was generated with [Mocha's](https://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation.
22
18
 
23
19
  ## Request basics
24
20
 
25
- A request can be initiated by invoking the appropriate method on the `request` object, then calling `.end()` to send the request. For example a simple __GET__ request:
21
+ A request can be initiated by invoking the appropriate method on the `request` object, then calling `.then()` (or `.end()` [or `await`](#promise-and-generator-support)) to send the request. For example a simple __GET__ request:
26
22
 
27
23
  request
28
24
  .get('/search')
29
- .end(function(err, res){
30
-
25
+ .then(res => {
26
+ // res.body, res.headers, res.status
27
+ })
28
+ .catch(err => {
29
+ // err.message, err.response
31
30
  });
32
31
 
33
- A method string may also be passed:
32
+ HTTP method may also be passed as a string:
34
33
 
35
- request('GET', '/search').end(callback);
34
+ request('GET', '/search').then(success, failure);
36
35
 
37
- ES6 promises are supported. *Instead* of `.end()` you can call `.then()`:
36
+ Old-style callbacks are also supported, but not recommended. *Instead of* `.then()` you can call `.end()`:
38
37
 
39
- request('GET', '/search').then(success, failure);
38
+ request('GET', '/search').end(function(err, res){
39
+ if (res.ok) {}
40
+ });
40
41
 
41
- The __Node__ client may also provide absolute URLs. In browsers absolute URLs won't work unless the server implements [CORS](#cors).
42
+ Absolute URLs can be used. In web browsers absolute URLs work only if the server implements [CORS](#cors).
42
43
 
43
44
  request
44
- .get('http://example.com/search')
45
- .end(function(err, res){
45
+ .get('https://example.com/search')
46
+ .then(res => {
46
47
 
47
48
  });
48
49
 
49
- The __Node__ client supports making requests to [Unix Domain Sockets](http://en.wikipedia.org/wiki/Unix_domain_socket):
50
+ The __Node__ client supports making requests to [Unix Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket):
50
51
 
51
52
  // pattern: https?+unix://SOCKET_PATH/REQUEST_PATH
52
53
  // Use `%2F` as `/` in SOCKET_PATH
53
54
  request
54
55
  .get('http+unix://%2Fabsolute%2Fpath%2Fto%2Funix.sock/search')
55
- .end(function(err, res){
56
+ .then(res => {
56
57
 
57
58
  });
58
59
 
@@ -60,15 +61,15 @@ __DELETE__, __HEAD__, __PATCH__, __POST__, and __PUT__ requests can also be used
60
61
 
61
62
  request
62
63
  .head('/favicon.ico')
63
- .end(function(err, res){
64
+ .then(res => {
64
65
 
65
66
  });
66
67
 
67
68
  __DELETE__ can be also called as `.del()` for compatibility with old IE where `delete` is a reserved word.
68
69
 
69
- The HTTP method defaults to __GET__, so if you wish, the following is valid:
70
+ The HTTP method defaults to __GET__, so if you wish, the following is valid:
70
71
 
71
- request('/search', function(err, res){
72
+ request('/search', (err, res) => {
72
73
 
73
74
  });
74
75
 
@@ -80,14 +81,14 @@ Setting header fields is simple, invoke `.set()` with a field name and value:
80
81
  .get('/search')
81
82
  .set('API-Key', 'foobar')
82
83
  .set('Accept', 'application/json')
83
- .end(callback);
84
+ .then(callback);
84
85
 
85
86
  You may also pass an object to set several fields in a single call:
86
87
 
87
88
  request
88
89
  .get('/search')
89
90
  .set({ 'API-Key': 'foobar', Accept: 'application/json' })
90
- .end(callback);
91
+ .then(callback);
91
92
 
92
93
  ## `GET` requests
93
94
 
@@ -98,7 +99,7 @@ The `.query()` method accepts objects, which when used with the __GET__ method w
98
99
  .query({ query: 'Manny' })
99
100
  .query({ range: '1..5' })
100
101
  .query({ order: 'desc' })
101
- .end(function(err, res){
102
+ .then(res => {
102
103
 
103
104
  });
104
105
 
@@ -107,7 +108,7 @@ Or as a single object:
107
108
  request
108
109
  .get('/search')
109
110
  .query({ query: 'Manny', range: '1..5', order: 'desc' })
110
- .end(function(err, res){
111
+ .then(res => {
111
112
 
112
113
  });
113
114
 
@@ -116,7 +117,7 @@ The `.query()` method accepts strings as well:
116
117
  request
117
118
  .get('/querystring')
118
119
  .query('search=Manny&range=1..5')
119
- .end(function(err, res){
120
+ .then(res => {
120
121
 
121
122
  });
122
123
 
@@ -126,7 +127,7 @@ Or joined:
126
127
  .get('/querystring')
127
128
  .query('search=Manny')
128
129
  .query('range=1..5')
129
- .end(function(err, res){
130
+ .then(res => {
130
131
 
131
132
  });
132
133
 
@@ -137,7 +138,7 @@ You can also use the `.query()` method for HEAD requests. The following will pro
137
138
  request
138
139
  .head('/users')
139
140
  .query({ email: 'joe@smith.com' })
140
- .end(function(err, res){
141
+ .then(res => {
141
142
 
142
143
  });
143
144
 
@@ -148,20 +149,20 @@ A typical JSON __POST__ request might look a little like the following, where we
148
149
  request.post('/user')
149
150
  .set('Content-Type', 'application/json')
150
151
  .send('{"name":"tj","pet":"tobi"}')
151
- .end(callback)
152
+ .then(callback)
152
153
 
153
154
  Since JSON is undoubtedly the most common, it's the _default_! The following example is equivalent to the previous.
154
155
 
155
156
  request.post('/user')
156
157
  .send({ name: 'tj', pet: 'tobi' })
157
- .end(callback)
158
+ .then(callback)
158
159
 
159
160
  Or using multiple `.send()` calls:
160
161
 
161
162
  request.post('/user')
162
163
  .send({ name: 'tj' })
163
164
  .send({ pet: 'tobi' })
164
- .end(callback)
165
+ .then(callback)
165
166
 
166
167
  By default sending strings will set the `Content-Type` to `application/x-www-form-urlencoded`,
167
168
  multiple calls will be concatenated with `&`, here resulting in `name=tj&pet=tobi`:
@@ -169,7 +170,7 @@ By default sending strings will set the `Content-Type` to `application/x-www-for
169
170
  request.post('/user')
170
171
  .send('name=tj')
171
172
  .send('pet=tobi')
172
- .end(callback);
173
+ .then(callback);
173
174
 
174
175
  SuperAgent formats are extensible, however by default "json" and "form" are supported. To send the data as `application/x-www-form-urlencoded` simply invoke `.type()` with "form", where the default is "json". This request will __POST__ the body "name=tj&pet=tobi".
175
176
 
@@ -177,13 +178,13 @@ SuperAgent formats are extensible, however by default "json" and "form" are supp
177
178
  .type('form')
178
179
  .send({ name: 'tj' })
179
180
  .send({ pet: 'tobi' })
180
- .end(callback)
181
+ .then(callback)
181
182
 
182
183
  Sending a [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData) object is also supported. The following example will __POST__ the content of the HTML form identified by id="myForm":
183
184
 
184
185
  request.post('/user')
185
186
  .send(new FormData(document.getElementById('myForm')))
186
- .end(callback)
187
+ .then(callback)
187
188
 
188
189
  ## Setting the `Content-Type`
189
190
 
@@ -207,8 +208,28 @@ simply the extension name such as "xml", "json", "png", etc:
207
208
 
208
209
  ## Serializing request body
209
210
 
210
- SuperAgent will automatically serialize JSON and forms. If you want to send the payload in a custom format, you can replace the built-in serialization with `.serialize()` method.
211
+ SuperAgent will automatically serialize JSON and forms.
212
+ You can setup automatic serialization for other types as well:
213
+
214
+ ```js
215
+ request.serialize['application/xml'] = function (obj) {
216
+ return 'string generated from obj';
217
+ };
218
+
219
+ // going forward, all requests with a Content-type of
220
+ // 'application/xml' will be automatically serialized
221
+ ```
222
+ If you want to send the payload in a custom format, you can replace
223
+ the built-in serialization with the `.serialize()` method on a per-request basis:
211
224
 
225
+ ```js
226
+ request
227
+ .post('/user')
228
+ .send({foo: 'bar'})
229
+ .serialize(obj => {
230
+ return 'string generated from obj';
231
+ });
232
+ ```
212
233
  ## Retrying requests
213
234
 
214
235
  When given the `.retry()` method, SuperAgent will automatically retry requests, if they fail in a way that is transient or could be due to a flaky Internet connection.
@@ -216,9 +237,10 @@ When given the `.retry()` method, SuperAgent will automatically retry requests,
216
237
  This method has two optional arguments: number of retries (default 3) and a callback. It calls `callback(err, res)` before each retry. The callback may return `true`/`false` to control whether the request sould be retried (but the maximum number of retries is always applied).
217
238
 
218
239
  request
219
- .get('http://example.com/search')
220
- .retry(2)
221
- .end(callback);
240
+ .get('https://example.com/search')
241
+ .retry(2) // or:
242
+ .retry(2, callback)
243
+ .then(finished);
222
244
 
223
245
  Use `.retry()` only with requests that are *idempotent* (i.e. multiple requests reaching the server won't cause undesirable side effects like duplicate purchases).
224
246
 
@@ -248,7 +270,7 @@ If you are calling Facebook's API, be sure to send an `Accept: application/json`
248
270
  .query({ format: 'json' })
249
271
  .query({ dest: '/login' })
250
272
  .send({ post: 'data', here: 'wahoo' })
251
- .end(callback);
273
+ .then(callback);
252
274
 
253
275
  By default the query string is not assembled in any particular order. An asciibetically-sorted query string can be enabled with `req.sortQuery()`. You may also provide a custom sorting comparison function with `req.sortQuery(myComparisonFn)`. The comparison function should take 2 arguments and return a negative/zero/positive integer.
254
276
 
@@ -258,16 +280,14 @@ By default the query string is not assembled in any particular order. An asciibe
258
280
  .query('name=Nick')
259
281
  .query('search=Manny')
260
282
  .sortQuery()
261
- .end(callback)
283
+ .then(callback)
262
284
 
263
285
  // customized sort function
264
286
  request.get('/user')
265
287
  .query('name=Nick')
266
288
  .query('search=Manny')
267
- .sortQuery(function(a, b){
268
- return a.length - b.length;
269
- })
270
- .end(callback)
289
+ .sortQuery((a, b) => a.length - b.length)
290
+ .then(callback)
271
291
  ```
272
292
 
273
293
  ## TLS options
@@ -289,7 +309,7 @@ request
289
309
  .post('/client-auth')
290
310
  .key(key)
291
311
  .cert(cert)
292
- .end(callback);
312
+ .then(callback);
293
313
  ```
294
314
 
295
315
  ```js
@@ -298,12 +318,32 @@ var ca = fs.readFileSync('ca.cert.pem');
298
318
  request
299
319
  .post('https://localhost/private-ca-server')
300
320
  .ca(ca)
301
- .end(callback);
321
+ .then(res => {});
302
322
  ```
303
323
 
304
324
  ## Parsing response bodies
305
325
 
306
- SuperAgent will parse known response-body data for you, currently supporting `application/x-www-form-urlencoded`, `application/json`, and `multipart/form-data`.
326
+ SuperAgent will parse known response-body data for you,
327
+ currently supporting `application/x-www-form-urlencoded`,
328
+ `application/json`, and `multipart/form-data`. You can setup
329
+ automatic parsing for other response-body data as well:
330
+
331
+ ```js
332
+ //browser
333
+ request.parse['application/xml'] = function (str) {
334
+ return {'object': 'parsed from str'};
335
+ };
336
+
337
+ //node
338
+ request.parse['application/xml'] = function (res, cb) {
339
+ //parse response text and set res.body here
340
+
341
+ cb(null, res);
342
+ };
343
+
344
+ //going forward, responses of type 'application/xml'
345
+ //will be parsed automatically
346
+ ```
307
347
 
308
348
  You can set a custom parser (that takes precedence over built-in parsers) with the `.buffer(true).parse(fn)` method. If response buffering is not enabled (`.buffer(false)`) then the `response` event will be emitted without waiting for the body parser to finish, so `response.body` won't be available.
309
349
 
@@ -341,7 +381,7 @@ In browsers, you may use `.responseType('blob')` to request handling of binary r
341
381
  ```js
342
382
  req.get('/binary.data')
343
383
  .responseType('blob')
344
- .end(function (error, res) {
384
+ .then(res => {
345
385
  // res.body will be a browser native Blob type here
346
386
  });
347
387
  ```
@@ -402,11 +442,11 @@ To abort requests simply invoke the `req.abort()` method.
402
442
 
403
443
  Sometimes networks and servers get "stuck" and never respond after accepting a request. Set timeouts to avoid requests waiting forever.
404
444
 
405
- * `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all redirects) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
445
+ * `req.timeout({deadline:ms})` or `req.timeout(ms)` (where `ms` is a number of milliseconds > 0) sets a deadline for the entire request (including all uploads, redirects, server processing time) to complete. If the response isn't fully downloaded within that time, the request will be aborted.
406
446
 
407
- * `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be a few seconds longer than just the time it takes server to respond, because it also includes time to make DNS lookup, TCP/IP and TLS connections.
447
+ * `req.timeout({response:ms})` sets maximum time to wait for the first byte to arrive from the server, but it does not limit how long the entire download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.
408
448
 
409
- You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks.
449
+ You should use both `deadline` and `response` timeouts. This way you can use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow, but reliable, networks. Note that both of these timers limit how long *uploads* of attached files are allowed to take. Use long timeouts if you're uploading files.
410
450
 
411
451
  request
412
452
  .get('/big-file?network=slow')
@@ -414,8 +454,10 @@ You should use both `deadline` and `response` timeouts. This way you can use a s
414
454
  response: 5000, // Wait 5 seconds for the server to start sending,
415
455
  deadline: 60000, // but allow 1 minute for the file to finish loading.
416
456
  })
417
- .end(function(err, res){
418
- if (err.timeout) { /* timed out! */ }
457
+ .then(res => {
458
+ /* responded in time */
459
+ }, err => {
460
+ if (err.timeout) { /* timed out! */ } else { /* other error */ }
419
461
  });
420
462
 
421
463
  Timeout errors have a `.timeout` property.
@@ -427,12 +469,12 @@ In both Node and browsers auth available via the `.auth()` method:
427
469
  request
428
470
  .get('http://local')
429
471
  .auth('tobi', 'learnboost')
430
- .end(callback);
472
+ .then(callback);
431
473
 
432
474
 
433
475
  In the _Node_ client Basic auth can be in the URL as "user:pass":
434
476
 
435
- request.get('http://tobi:learnboost@local').end(callback);
477
+ request.get('http://tobi:learnboost@local').then(callback);
436
478
 
437
479
  By default only `Basic` auth is used. In browser you can add `{type:'auto'}` to enable all methods built-in in the browser (Digest, NTLM, etc.):
438
480
 
@@ -445,7 +487,7 @@ By default up to 5 redirects will be followed, however you may specify this with
445
487
  request
446
488
  .get('/some.png')
447
489
  .redirects(2)
448
- .end(callback);
490
+ .then(callback);
449
491
 
450
492
  ## Agents for global state
451
493
 
@@ -464,7 +506,7 @@ In browsers cookies are managed automatically by the browser, so the `.agent()`
464
506
 
465
507
  ### Default options for multiple requests
466
508
 
467
- Regular request methods (`.use()`, `.set()`, `.auth()`) called on the agent will be used as defaults for all requests made by that agent.
509
+ Regular request methods called on the agent will be used as defaults for all requests made by that agent.
468
510
 
469
511
  const agent = request.agent()
470
512
  .use(plugin)
@@ -473,9 +515,13 @@ Regular request methods (`.use()`, `.set()`, `.auth()`) called on the agent will
473
515
  await agent.get('/with-plugin-and-auth');
474
516
  await agent.get('/also-with-plugin-and-auth');
475
517
 
518
+ The complete list of methods that the agent can use to set defaults is: `use`, `on`, `once`, `set`, `query`, `type`, `accept`, `auth`, `withCredentials`, `sortQuery`, `retry`, `ok`, `redirects`, `timeout`, `buffer`, `serialize`, `parse`, `ca`, `key`, `pfx`, `cert`.
519
+
476
520
  ## Piping data
477
521
 
478
- The Node client allows you to pipe data to and from the request. For example piping a file's contents as the request:
522
+ The Node client allows you to pipe data to and from the request. Please note that `.pipe()` is used **instead of** `.end()`/`.then()` methods.
523
+
524
+ For example piping a file's contents as the request:
479
525
 
480
526
  const request = require('superagent');
481
527
  const fs = require('fs');
@@ -493,6 +539,22 @@ Or piping the response to a file:
493
539
  const req = request.get('/some.json');
494
540
  req.pipe(stream);
495
541
 
542
+ It's not possible to mix pipes and callbacks or promises. Note that you should **NOT** attempt to pipe the result of `.end()` or the `Response` object:
543
+
544
+ // Don't do either of these:
545
+ const stream = getAWritableStream();
546
+ const req = request
547
+ .get('/some.json')
548
+ // BAD: this pipes garbage to the stream and fails in unexpected ways
549
+ .end((err, this_does_not_work) => this_does_not_work.pipe(stream))
550
+ const req = request
551
+ .get('/some.json')
552
+ .end()
553
+ // BAD: this is also unsupported, .pipe calls .end for you.
554
+ .pipe(nope_its_too_late);
555
+
556
+ In a [future version](https://github.com/visionmedia/superagent/issues/1188) of superagent, improper calls to `pipe()` will fail.
557
+
496
558
  ## Multipart requests
497
559
 
498
560
  SuperAgent is also great for _building_ multipart requests for which it provides methods `.attach()` and `.field()`.
@@ -503,7 +565,7 @@ When you use `.field()` or `.attach()` you can't use `.send()` and you *must not
503
565
 
504
566
  To send a file use `.attach(name, [file], [options])`. You can attach multiple files by calling `.attach` multiple times. The arguments are:
505
567
 
506
- * `name` — filed name in the form.
568
+ * `name` — field name in the form.
507
569
  * `file` — either string with file path or `Blob`/`Buffer` object.
508
570
  * `options` — (optional) either string with custom file name or `{filename: string}` object. In Node also `{contentType: 'mime/type'}` is supported. In browser create a `Blob` with an appropriate type instead.
509
571
 
@@ -514,7 +576,7 @@ To send a file use `.attach(name, [file], [options])`. You can attach multiple f
514
576
  .attach('image1', 'path/to/felix.jpeg')
515
577
  .attach('image2', imageBuffer, 'luna.jpeg')
516
578
  .field('caption', 'My cats')
517
- .end(callback);
579
+ .then(callback);
518
580
 
519
581
  ### Field values
520
582
 
@@ -526,7 +588,7 @@ Much like form fields in HTML, you can set field values with `.field(name, value
526
588
  .field('user[email]', 'tobi@learnboost.com')
527
589
  .field('friends[]', ['loki', 'jane'])
528
590
  .attach('image', 'path/to/tobi.png')
529
- .end(callback);
591
+ .then(callback);
530
592
 
531
593
  ## Compression
532
594
 
@@ -545,9 +607,9 @@ For security reasons, browsers will block cross-origin requests unless the serve
545
607
  The `.withCredentials()` method enables the ability to send cookies from the origin, however only when `Access-Control-Allow-Origin` is _not_ a wildcard ("*"), and `Access-Control-Allow-Credentials` is "true".
546
608
 
547
609
  request
548
- .get('http://api.example.com:4001/')
610
+ .get('https://api.example.com:4001/')
549
611
  .withCredentials()
550
- .then(function(res){
612
+ .then(res => {
551
613
  assert.equal(200, res.status);
552
614
  assert.equal('tobi', res.text);
553
615
  })
@@ -559,7 +621,7 @@ Your callback function will always be passed two arguments: error and response.
559
621
  request
560
622
  .post('/upload')
561
623
  .attach('image', 'path/to/tobi.png')
562
- .end(function(err, res){
624
+ .then(res => {
563
625
 
564
626
  });
565
627
 
@@ -569,7 +631,7 @@ An "error" event is also emitted, with you can listen for:
569
631
  .post('/upload')
570
632
  .attach('image', 'path/to/tobi.png')
571
633
  .on('error', handle)
572
- .end(function(err, res){
634
+ .then(res => {
573
635
 
574
636
  });
575
637
 
@@ -609,11 +671,13 @@ SuperAgent fires `progress` events on upload and download of large files.
609
671
  loaded: // bytes downloaded or uploaded so far
610
672
  } */
611
673
  })
612
- .end()
674
+ .then()
613
675
 
614
676
  ## Promise and Generator support
615
677
 
616
- SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax. Do not call `.end()` if you're using promises.
678
+ SuperAgent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax.
679
+
680
+ If you're using promises, **do not** call `.end()` or `.pipe()`. Any use of `.then()` or `await` disables all other ways of using the request.
617
681
 
618
682
  Libraries like [co](https://github.com/tj/co) or a web framework like [koa](https://github.com/koajs/koa) can `yield` on any SuperAgent method:
619
683
 
@@ -632,4 +696,4 @@ If want to use WebPack to compile code for Node.JS, you *must* specify [node tar
632
696
 
633
697
  ### Using browser version in electron
634
698
 
635
- [Electron](http://electron.atom.io/) developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.
699
+ [Electron](https://electron.atom.io/) developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.