superagent 3.4.0 → 3.4.4
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/History.md +13 -0
- package/lib/client.js +21 -9
- package/lib/node/index.js +54 -55
- package/lib/request-base.js +7 -3
- package/package.json +3 -4
- package/superagent.js +29 -13
- package/changelog.sh +0 -7
- package/test.js +0 -8
- package/yarn.lock +0 -3647
package/History.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# 3.4.3 (2017-02-14)
|
|
2
|
+
|
|
3
|
+
* Fixed being able to define own parsers when their mime type starts with `text/` (Damien Clark)
|
|
4
|
+
* `withCredentials(false)` (Andy Woods)
|
|
5
|
+
* Use `formData.on` instead of `.once` (Kornel Lesiński)
|
|
6
|
+
* Ignore `attach("file",null)` (Kornel Lesiński)
|
|
7
|
+
|
|
8
|
+
# 3.4.1 (2017-01-29)
|
|
9
|
+
|
|
10
|
+
* Allow `retry()` and `retry(0)` (Alexander Pope)
|
|
11
|
+
* Allow optional body/data in DELETE requests (Alpha Shuro)
|
|
12
|
+
* Fixed query string on retried requests (Kornel Lesiński)
|
|
13
|
+
|
|
1
14
|
# 3.4.0 (2017-01-25)
|
|
2
15
|
|
|
3
16
|
* New `.retry(n)` method and `err.retries` (Alexander Pope)
|
package/lib/client.js
CHANGED
|
@@ -12,7 +12,7 @@ if (typeof window !== 'undefined') { // Browser window
|
|
|
12
12
|
root = this;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
var Emitter = require('emitter');
|
|
15
|
+
var Emitter = require('component-emitter');
|
|
16
16
|
var RequestBase = require('./request-base');
|
|
17
17
|
var isObject = require('./is-object');
|
|
18
18
|
var isFunction = require('./is-function');
|
|
@@ -501,13 +501,16 @@ Request.prototype.accept = function(type){
|
|
|
501
501
|
* Set Authorization field value with `user` and `pass`.
|
|
502
502
|
*
|
|
503
503
|
* @param {String} user
|
|
504
|
-
* @param {String} pass
|
|
505
|
-
* @param {Object} options with 'type' property 'auto' or '
|
|
504
|
+
* @param {String} [pass] optional in case of using 'bearer' as type
|
|
505
|
+
* @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
|
|
506
506
|
* @return {Request} for chaining
|
|
507
507
|
* @api public
|
|
508
508
|
*/
|
|
509
509
|
|
|
510
510
|
Request.prototype.auth = function(user, pass, options){
|
|
511
|
+
if (typeof pass === 'object' && pass !== null) { // pass is optional and can substitute for options
|
|
512
|
+
options = pass;
|
|
513
|
+
}
|
|
511
514
|
if (!options) {
|
|
512
515
|
options = {
|
|
513
516
|
type: 'function' === typeof btoa ? 'basic' : 'auto',
|
|
@@ -523,6 +526,10 @@ Request.prototype.auth = function(user, pass, options){
|
|
|
523
526
|
this.username = user;
|
|
524
527
|
this.password = pass;
|
|
525
528
|
break;
|
|
529
|
+
|
|
530
|
+
case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
|
|
531
|
+
this.set('Authorization', 'Bearer ' + user);
|
|
532
|
+
break;
|
|
526
533
|
}
|
|
527
534
|
return this;
|
|
528
535
|
};
|
|
@@ -565,11 +572,13 @@ Request.prototype.query = function(val){
|
|
|
565
572
|
*/
|
|
566
573
|
|
|
567
574
|
Request.prototype.attach = function(field, file, options){
|
|
568
|
-
if (
|
|
569
|
-
|
|
570
|
-
|
|
575
|
+
if (file) {
|
|
576
|
+
if (this._data) {
|
|
577
|
+
throw Error("superagent can't mix .send() and .attach()");
|
|
578
|
+
}
|
|
571
579
|
|
|
572
|
-
|
|
580
|
+
this._getFormData().append(field, file, options || file.name);
|
|
581
|
+
}
|
|
573
582
|
return this;
|
|
574
583
|
};
|
|
575
584
|
|
|
@@ -847,16 +856,19 @@ request.options = function(url, data, fn){
|
|
|
847
856
|
};
|
|
848
857
|
|
|
849
858
|
/**
|
|
850
|
-
* DELETE `url` with optional callback `fn(res)`.
|
|
859
|
+
* DELETE `url` with optional `data` and callback `fn(res)`.
|
|
851
860
|
*
|
|
852
861
|
* @param {String} url
|
|
862
|
+
* @param {Mixed} [data]
|
|
853
863
|
* @param {Function} [fn]
|
|
854
864
|
* @return {Request}
|
|
855
865
|
* @api public
|
|
856
866
|
*/
|
|
857
867
|
|
|
858
|
-
function del(url, fn){
|
|
868
|
+
function del(url, data, fn){
|
|
859
869
|
var req = request('DELETE', url);
|
|
870
|
+
if ('function' == typeof data) fn = data, data = null;
|
|
871
|
+
if (data) req.send(data);
|
|
860
872
|
if (fn) req.end(fn);
|
|
861
873
|
return req;
|
|
862
874
|
};
|
package/lib/node/index.js
CHANGED
|
@@ -183,34 +183,37 @@ RequestBase(Request.prototype);
|
|
|
183
183
|
*/
|
|
184
184
|
|
|
185
185
|
Request.prototype.attach = function(field, file, options){
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
if (file) {
|
|
187
|
+
if (this._data) {
|
|
188
|
+
throw Error("superagent can't mix .send() and .attach()");
|
|
189
|
+
}
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
var o = options || {};
|
|
192
|
+
if ('string' == typeof options) {
|
|
193
|
+
o = { filename: options };
|
|
194
|
+
}
|
|
194
195
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
196
|
+
if ('string' == typeof file) {
|
|
197
|
+
if (!o.filename) o.filename = file;
|
|
198
|
+
debug('creating `fs.ReadStream` instance for file: %s', file);
|
|
199
|
+
file = fs.createReadStream(file);
|
|
200
|
+
} else if (!o.filename && file.path) {
|
|
201
|
+
o.filename = file.path;
|
|
202
|
+
}
|
|
202
203
|
|
|
203
|
-
|
|
204
|
+
this._getFormData().append(field, file, o);
|
|
205
|
+
}
|
|
204
206
|
return this;
|
|
205
207
|
};
|
|
206
208
|
|
|
207
209
|
Request.prototype._getFormData = function() {
|
|
208
210
|
if (!this._formData) {
|
|
209
211
|
this._formData = new FormData();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
var that = this;
|
|
213
|
+
this._formData.on('error', function(err) {
|
|
214
|
+
that.emit('error', err);
|
|
215
|
+
that.abort();
|
|
216
|
+
});
|
|
214
217
|
}
|
|
215
218
|
return this._formData;
|
|
216
219
|
};
|
|
@@ -324,12 +327,6 @@ Request.prototype.write = function(data, encoding){
|
|
|
324
327
|
var req = this.request();
|
|
325
328
|
if (!this._streamRequest) {
|
|
326
329
|
this._streamRequest = true;
|
|
327
|
-
try {
|
|
328
|
-
// ensure querystring is appended before headers are sent
|
|
329
|
-
this._appendQueryString(req);
|
|
330
|
-
} catch (e) {
|
|
331
|
-
return this.emit('error', e);
|
|
332
|
-
}
|
|
333
330
|
}
|
|
334
331
|
return req.write(data, encoding);
|
|
335
332
|
};
|
|
@@ -471,18 +468,30 @@ Request.prototype._redirect = function(res){
|
|
|
471
468
|
* .auth('tobi', 'learnboost')
|
|
472
469
|
* .auth('tobi:learnboost')
|
|
473
470
|
* .auth('tobi')
|
|
471
|
+
* .auth(accessToken, { type: 'bearer' })
|
|
474
472
|
*
|
|
475
473
|
* @param {String} user
|
|
476
|
-
* @param {String} pass
|
|
474
|
+
* @param {String} [pass]
|
|
475
|
+
* @param {Object} [options] options with authorization type 'basic' or 'bearer' ('basic' is default)
|
|
477
476
|
* @return {Request} for chaining
|
|
478
477
|
* @api public
|
|
479
478
|
*/
|
|
480
479
|
|
|
481
|
-
Request.prototype.auth = function(user, pass){
|
|
480
|
+
Request.prototype.auth = function(user, pass, options){
|
|
482
481
|
if (1 === arguments.length) pass = '';
|
|
483
|
-
if (
|
|
484
|
-
|
|
485
|
-
|
|
482
|
+
if (2 === arguments.length && typeof pass === 'object') options = pass;
|
|
483
|
+
if (!options) {
|
|
484
|
+
options = { type: 'basic' };
|
|
485
|
+
}
|
|
486
|
+
switch (options.type) {
|
|
487
|
+
case 'bearer':
|
|
488
|
+
return this.set('Authorization', 'Bearer ' + user);
|
|
489
|
+
|
|
490
|
+
default: // 'basic'
|
|
491
|
+
if (!~user.indexOf(':')) user = user + ':';
|
|
492
|
+
var str = new Buffer(user + pass).toString('base64');
|
|
493
|
+
return this.set('Authorization', 'Basic ' + str);
|
|
494
|
+
}
|
|
486
495
|
};
|
|
487
496
|
|
|
488
497
|
/**
|
|
@@ -600,7 +609,7 @@ Request.prototype.request = function(){
|
|
|
600
609
|
// if not the same, we are in the **old** (cancelled) request,
|
|
601
610
|
// so need to continue (same as for above)
|
|
602
611
|
if (self._retries !== retries) return;
|
|
603
|
-
// if we've
|
|
612
|
+
// if we've received a response then we don't want to let
|
|
604
613
|
// an error in the request blow up the response
|
|
605
614
|
if (self.response) return;
|
|
606
615
|
self.callback(err);
|
|
@@ -623,6 +632,12 @@ Request.prototype.request = function(){
|
|
|
623
632
|
req.setHeader(key, this.header[key]);
|
|
624
633
|
}
|
|
625
634
|
|
|
635
|
+
try {
|
|
636
|
+
this._appendQueryString(req);
|
|
637
|
+
} catch (e) {
|
|
638
|
+
return this.emit('error', e);
|
|
639
|
+
}
|
|
640
|
+
|
|
626
641
|
return req;
|
|
627
642
|
};
|
|
628
643
|
|
|
@@ -731,7 +746,7 @@ Request.prototype._emitResponse = function(body, files){
|
|
|
731
746
|
};
|
|
732
747
|
|
|
733
748
|
Request.prototype.end = function(fn){
|
|
734
|
-
|
|
749
|
+
this.request();
|
|
735
750
|
debug('%s %s', this.method, this.url);
|
|
736
751
|
|
|
737
752
|
if (this._endCalled) {
|
|
@@ -742,13 +757,6 @@ Request.prototype.end = function(fn){
|
|
|
742
757
|
// store callback
|
|
743
758
|
this._callback = fn || noop;
|
|
744
759
|
|
|
745
|
-
// querystring
|
|
746
|
-
try {
|
|
747
|
-
this._appendQueryString(req);
|
|
748
|
-
} catch (e) {
|
|
749
|
-
return this.callback(e);
|
|
750
|
-
}
|
|
751
|
-
|
|
752
760
|
return this._end();
|
|
753
761
|
};
|
|
754
762
|
|
|
@@ -826,14 +834,14 @@ Request.prototype._end = function() {
|
|
|
826
834
|
var form = new formidable.IncomingForm();
|
|
827
835
|
parser = form.parse.bind(form);
|
|
828
836
|
buffer = true;
|
|
829
|
-
} else if (
|
|
837
|
+
} else if (isImageOrVideo(mime)) {
|
|
830
838
|
parser = exports.parse.image;
|
|
831
839
|
buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent
|
|
840
|
+
} else if (exports.parse[mime]) {
|
|
841
|
+
parser = exports.parse[mime];
|
|
832
842
|
} else if ('text' == type) {
|
|
833
843
|
parser = exports.parse.text;
|
|
834
844
|
buffer = (buffer !== false);
|
|
835
|
-
} else if (exports.parse[mime]) {
|
|
836
|
-
parser = exports.parse[mime];
|
|
837
845
|
|
|
838
846
|
// everyone wants their own white-labeled json
|
|
839
847
|
} else if (isJSON(mime)) {
|
|
@@ -1012,19 +1020,10 @@ function isText(mime) {
|
|
|
1012
1020
|
|| 'x-www-form-urlencoded' == subtype;
|
|
1013
1021
|
}
|
|
1014
1022
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
*
|
|
1018
|
-
* @param {String} mime
|
|
1019
|
-
* @return {Boolean}
|
|
1020
|
-
* @api public
|
|
1021
|
-
*/
|
|
1022
|
-
|
|
1023
|
-
function isImage(mime) {
|
|
1024
|
-
var parts = mime.split('/');
|
|
1025
|
-
var type = parts[0];
|
|
1023
|
+
function isImageOrVideo(mime) {
|
|
1024
|
+
var type = mime.split('/')[0];
|
|
1026
1025
|
|
|
1027
|
-
return 'image' == type;
|
|
1026
|
+
return 'image' == type || 'video' == type;
|
|
1028
1027
|
}
|
|
1029
1028
|
|
|
1030
1029
|
/**
|
|
@@ -1049,4 +1048,4 @@ function isJSON(mime) {
|
|
|
1049
1048
|
|
|
1050
1049
|
function isRedirect(code) {
|
|
1051
1050
|
return ~[301, 302, 303, 305, 307, 308].indexOf(code);
|
|
1052
|
-
}
|
|
1051
|
+
}
|
package/lib/request-base.js
CHANGED
|
@@ -140,7 +140,10 @@ RequestBase.prototype.timeout = function timeout(options){
|
|
|
140
140
|
*/
|
|
141
141
|
|
|
142
142
|
RequestBase.prototype.retry = function retry(count){
|
|
143
|
-
|
|
143
|
+
// Default to 1 if no count passed or true
|
|
144
|
+
if (arguments.length === 0 || count === true) count = 1;
|
|
145
|
+
if (count <= 0) count = 0;
|
|
146
|
+
this._maxRetries = count;
|
|
144
147
|
this._retries = 0;
|
|
145
148
|
return this;
|
|
146
149
|
};
|
|
@@ -384,9 +387,10 @@ RequestBase.prototype.abort = function(){
|
|
|
384
387
|
* @api public
|
|
385
388
|
*/
|
|
386
389
|
|
|
387
|
-
RequestBase.prototype.withCredentials = function(){
|
|
390
|
+
RequestBase.prototype.withCredentials = function(on){
|
|
388
391
|
// This is browser-only functionality. Node side is no-op.
|
|
389
|
-
|
|
392
|
+
if(on==undefined) on = true;
|
|
393
|
+
this._withCredentials = on;
|
|
390
394
|
return this;
|
|
391
395
|
};
|
|
392
396
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superagent",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.4",
|
|
4
4
|
"description": "elegant & feature rich browser / node HTTP with a fluent API",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prepublish": "make all",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"debug": "^2.2.0",
|
|
30
30
|
"extend": "^3.0.0",
|
|
31
31
|
"form-data": "^2.1.1",
|
|
32
|
-
"formidable": "^1.
|
|
32
|
+
"formidable": "^1.1.1",
|
|
33
33
|
"methods": "^1.1.1",
|
|
34
34
|
"mime": "^1.3.4",
|
|
35
35
|
"qs": "^6.1.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"Base64": "^1.0.0",
|
|
40
40
|
"basic-auth-connect": "^1.0.0",
|
|
41
41
|
"body-parser": "^1.15.0",
|
|
42
|
-
"browserify": "^
|
|
42
|
+
"browserify": "^14.0.0",
|
|
43
43
|
"cookie-parser": "^1.4.1",
|
|
44
44
|
"express": "^4.13.4",
|
|
45
45
|
"express-session": "^1.13.0",
|
|
@@ -52,7 +52,6 @@
|
|
|
52
52
|
},
|
|
53
53
|
"browser": {
|
|
54
54
|
"./lib/node/index.js": "./lib/client.js",
|
|
55
|
-
"emitter": "component-emitter",
|
|
56
55
|
"./test/support/server.js": "./test/support/blank.js"
|
|
57
56
|
},
|
|
58
57
|
"component": {
|
package/superagent.js
CHANGED
|
@@ -173,7 +173,10 @@ RequestBase.prototype.timeout = function timeout(options){
|
|
|
173
173
|
*/
|
|
174
174
|
|
|
175
175
|
RequestBase.prototype.retry = function retry(count){
|
|
176
|
-
|
|
176
|
+
// Default to 1 if no count passed or true
|
|
177
|
+
if (arguments.length === 0 || count === true) count = 1;
|
|
178
|
+
if (count <= 0) count = 0;
|
|
179
|
+
this._maxRetries = count;
|
|
177
180
|
this._retries = 0;
|
|
178
181
|
return this;
|
|
179
182
|
};
|
|
@@ -417,9 +420,10 @@ RequestBase.prototype.abort = function(){
|
|
|
417
420
|
* @api public
|
|
418
421
|
*/
|
|
419
422
|
|
|
420
|
-
RequestBase.prototype.withCredentials = function(){
|
|
423
|
+
RequestBase.prototype.withCredentials = function(on){
|
|
421
424
|
// This is browser-only functionality. Node side is no-op.
|
|
422
|
-
|
|
425
|
+
if(on==undefined) on = true;
|
|
426
|
+
this._withCredentials = on;
|
|
423
427
|
return this;
|
|
424
428
|
};
|
|
425
429
|
|
|
@@ -1019,7 +1023,7 @@ if (typeof window !== 'undefined') { // Browser window
|
|
|
1019
1023
|
root = this;
|
|
1020
1024
|
}
|
|
1021
1025
|
|
|
1022
|
-
var Emitter = require('emitter');
|
|
1026
|
+
var Emitter = require('component-emitter');
|
|
1023
1027
|
var RequestBase = require('./request-base');
|
|
1024
1028
|
var isObject = require('./is-object');
|
|
1025
1029
|
var isFunction = require('./is-function');
|
|
@@ -1508,13 +1512,16 @@ Request.prototype.accept = function(type){
|
|
|
1508
1512
|
* Set Authorization field value with `user` and `pass`.
|
|
1509
1513
|
*
|
|
1510
1514
|
* @param {String} user
|
|
1511
|
-
* @param {String} pass
|
|
1512
|
-
* @param {Object} options with 'type' property 'auto' or '
|
|
1515
|
+
* @param {String} [pass] optional in case of using 'bearer' as type
|
|
1516
|
+
* @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
|
|
1513
1517
|
* @return {Request} for chaining
|
|
1514
1518
|
* @api public
|
|
1515
1519
|
*/
|
|
1516
1520
|
|
|
1517
1521
|
Request.prototype.auth = function(user, pass, options){
|
|
1522
|
+
if (typeof pass === 'object' && pass !== null) { // pass is optional and can substitute for options
|
|
1523
|
+
options = pass;
|
|
1524
|
+
}
|
|
1518
1525
|
if (!options) {
|
|
1519
1526
|
options = {
|
|
1520
1527
|
type: 'function' === typeof btoa ? 'basic' : 'auto',
|
|
@@ -1530,6 +1537,10 @@ Request.prototype.auth = function(user, pass, options){
|
|
|
1530
1537
|
this.username = user;
|
|
1531
1538
|
this.password = pass;
|
|
1532
1539
|
break;
|
|
1540
|
+
|
|
1541
|
+
case 'bearer': // usage would be .auth(accessToken, { type: 'bearer' })
|
|
1542
|
+
this.set('Authorization', 'Bearer ' + user);
|
|
1543
|
+
break;
|
|
1533
1544
|
}
|
|
1534
1545
|
return this;
|
|
1535
1546
|
};
|
|
@@ -1572,11 +1583,13 @@ Request.prototype.query = function(val){
|
|
|
1572
1583
|
*/
|
|
1573
1584
|
|
|
1574
1585
|
Request.prototype.attach = function(field, file, options){
|
|
1575
|
-
if (
|
|
1576
|
-
|
|
1577
|
-
|
|
1586
|
+
if (file) {
|
|
1587
|
+
if (this._data) {
|
|
1588
|
+
throw Error("superagent can't mix .send() and .attach()");
|
|
1589
|
+
}
|
|
1578
1590
|
|
|
1579
|
-
|
|
1591
|
+
this._getFormData().append(field, file, options || file.name);
|
|
1592
|
+
}
|
|
1580
1593
|
return this;
|
|
1581
1594
|
};
|
|
1582
1595
|
|
|
@@ -1854,16 +1867,19 @@ request.options = function(url, data, fn){
|
|
|
1854
1867
|
};
|
|
1855
1868
|
|
|
1856
1869
|
/**
|
|
1857
|
-
* DELETE `url` with optional callback `fn(res)`.
|
|
1870
|
+
* DELETE `url` with optional `data` and callback `fn(res)`.
|
|
1858
1871
|
*
|
|
1859
1872
|
* @param {String} url
|
|
1873
|
+
* @param {Mixed} [data]
|
|
1860
1874
|
* @param {Function} [fn]
|
|
1861
1875
|
* @return {Request}
|
|
1862
1876
|
* @api public
|
|
1863
1877
|
*/
|
|
1864
1878
|
|
|
1865
|
-
function del(url, fn){
|
|
1879
|
+
function del(url, data, fn){
|
|
1866
1880
|
var req = request('DELETE', url);
|
|
1881
|
+
if ('function' == typeof data) fn = data, data = null;
|
|
1882
|
+
if (data) req.send(data);
|
|
1867
1883
|
if (fn) req.end(fn);
|
|
1868
1884
|
return req;
|
|
1869
1885
|
};
|
|
@@ -1925,5 +1941,5 @@ request.put = function(url, data, fn){
|
|
|
1925
1941
|
return req;
|
|
1926
1942
|
};
|
|
1927
1943
|
|
|
1928
|
-
},{"./is-function":1,"./is-object":2,"./request-base":3,"./response-base":4,"./should-retry":5,"emitter":7}]},{},[8])(8)
|
|
1944
|
+
},{"./is-function":1,"./is-object":2,"./request-base":3,"./response-base":4,"./should-retry":5,"component-emitter":7}]},{},[8])(8)
|
|
1929
1945
|
});
|
package/changelog.sh
DELETED
package/test.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var request = require('.');
|
|
2
|
-
request.get('https://google.com').timeout(1140).end(function(err, res) { console.log(err); });
|
|
3
|
-
request.get('http://google.com').timeout(140).end(function(err, res) { console.log(err); });
|
|
4
|
-
request.get('https://google.com').timeout(40).end(function(err, res) { console.log(err); });
|
|
5
|
-
request.get('http://google.com').timeout(140).end(function(err, res) { console.log(err); });
|
|
6
|
-
request.get('https://google.com').timeout(140).end(function(err, res) { console.log(err); });
|
|
7
|
-
request.get('http://google.com').timeout(1140).end(function(err, res) { console.log(err); });
|
|
8
|
-
request.get('http://google.com').timeout(40).end(function(err, res) { console.log(err); });
|