@superhero/http-request 4.1.0 → 4.1.2
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/index.js +110 -82
- package/index.test.js +45 -1
- package/package.json +5 -2
package/index.js
CHANGED
|
@@ -18,8 +18,9 @@ import { setTimeout as wait } from 'node:timers/promises'
|
|
|
18
18
|
/**
|
|
19
19
|
* @typedef {Object} RequestOptions
|
|
20
20
|
*
|
|
21
|
-
* @property {String}
|
|
22
|
-
* @property {String}
|
|
21
|
+
* @property {String} [method] - The HTTP method to use.
|
|
22
|
+
* @property {String} url - The URL to make the request to.
|
|
23
|
+
* @property {String} base - The base path to resolve the URL against.
|
|
23
24
|
* @property {Object.<String, String>} [headers] - The request headers.
|
|
24
25
|
* @property {Object|String} [body] - The request body.
|
|
25
26
|
* @property {Object|String} [data] - Alias for body.
|
|
@@ -35,7 +36,6 @@ import { setTimeout as wait } from 'node:timers/promises'
|
|
|
35
36
|
* @property {Boolean} [doNotThrowOnRedirectStatus] - Set to true to avoid throwing on redirect status.
|
|
36
37
|
* @property {Stream.Readable>} [upstream] - An optional upstream stream to make it possible to pipe body to the upstream directly.
|
|
37
38
|
* @property {Stream.Writable} [downstream] - An optional downstream stream to make it possible to pipe body from the downstream to.
|
|
38
|
-
* @property {String} [method] - The HTTP method to use.
|
|
39
39
|
*
|
|
40
40
|
* @see {@link https://nodejs.org/api/http.html#httprequestoptions-callback}
|
|
41
41
|
* @see {@link https://nodejs.org/api/https.html#httpsrequestoptions-callback}
|
|
@@ -68,8 +68,8 @@ export default class Request
|
|
|
68
68
|
/**
|
|
69
69
|
* Connects to a HTTP/2 server.
|
|
70
70
|
*
|
|
71
|
-
* @param {String} authority the URL
|
|
72
|
-
* @param {Object} [options]
|
|
71
|
+
* @param {String|Object} [authority] the URL to connect to the server, or the options object
|
|
72
|
+
* @param {Object} [options] @see node:http2.connect options
|
|
73
73
|
*
|
|
74
74
|
* @throws {Error} E_HTTP_REQUEST_CONNECT_INVALID_ARGUMENT
|
|
75
75
|
*
|
|
@@ -77,31 +77,28 @@ export default class Request
|
|
|
77
77
|
*/
|
|
78
78
|
connect(authority, options)
|
|
79
79
|
{
|
|
80
|
-
return new Promise(async
|
|
80
|
+
return new Promise(async resolve =>
|
|
81
81
|
{
|
|
82
82
|
await this.close()
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
if('object' === typeof authority
|
|
85
|
+
&& null !== authority
|
|
86
|
+
&& false === !!options)
|
|
87
|
+
{
|
|
88
|
+
options = authority
|
|
89
|
+
authority = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
options = Object.assign(this.config, options)
|
|
93
|
+
const url = new URL(authority || options.authority || options.base || options.url)
|
|
87
94
|
|
|
88
|
-
this.config.
|
|
89
|
-
this.
|
|
90
|
-
this.http2Session = http2.connect(authority, options, () =>
|
|
95
|
+
this.config.authority = url.origin
|
|
96
|
+
this.http2Session = http2.connect(url.origin, options, () =>
|
|
91
97
|
{
|
|
92
98
|
this.http2Session.removeAllListeners('error')
|
|
93
99
|
this.http2Session.on('error', console.error)
|
|
94
100
|
|
|
95
|
-
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
// If there is a error on connection, reject the promise.
|
|
99
|
-
this.http2Session.once('error', (reason) =>
|
|
100
|
-
{
|
|
101
|
-
const error = new Error(`Failed to connect to server over HTTP2 using authority: ${authority}`)
|
|
102
|
-
error.code = 'E_HTTP_REQUEST_CONNECT_ERROR'
|
|
103
|
-
error.cause = reason
|
|
104
|
-
reject(error)
|
|
101
|
+
resolve()
|
|
105
102
|
})
|
|
106
103
|
})
|
|
107
104
|
}
|
|
@@ -113,7 +110,7 @@ export default class Request
|
|
|
113
110
|
*/
|
|
114
111
|
close()
|
|
115
112
|
{
|
|
116
|
-
return new Promise((
|
|
113
|
+
return new Promise((resolve, reject) =>
|
|
117
114
|
{
|
|
118
115
|
const http2Session = this.http2Session
|
|
119
116
|
|
|
@@ -129,7 +126,7 @@ export default class Request
|
|
|
129
126
|
|
|
130
127
|
error
|
|
131
128
|
? reject(error)
|
|
132
|
-
:
|
|
129
|
+
: resolve()
|
|
133
130
|
})
|
|
134
131
|
|
|
135
132
|
return // await the close event
|
|
@@ -138,8 +135,8 @@ export default class Request
|
|
|
138
135
|
delete this.http2Session
|
|
139
136
|
}
|
|
140
137
|
|
|
141
|
-
// fallback to
|
|
142
|
-
|
|
138
|
+
// fallback to resolve if nothing to close
|
|
139
|
+
resolve()
|
|
143
140
|
})
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -162,7 +159,9 @@ export default class Request
|
|
|
162
159
|
*/
|
|
163
160
|
get(options)
|
|
164
161
|
{
|
|
165
|
-
|
|
162
|
+
options = this.#normalizeOptions(options)
|
|
163
|
+
options.method = 'GET'
|
|
164
|
+
return this.fetch(options)
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
/**
|
|
@@ -175,7 +174,9 @@ export default class Request
|
|
|
175
174
|
*/
|
|
176
175
|
post(options)
|
|
177
176
|
{
|
|
178
|
-
|
|
177
|
+
options = this.#normalizeOptions(options)
|
|
178
|
+
options.method = 'POST'
|
|
179
|
+
return this.fetch(options)
|
|
179
180
|
}
|
|
180
181
|
|
|
181
182
|
/**
|
|
@@ -188,7 +189,9 @@ export default class Request
|
|
|
188
189
|
*/
|
|
189
190
|
put(options)
|
|
190
191
|
{
|
|
191
|
-
|
|
192
|
+
options = this.#normalizeOptions(options)
|
|
193
|
+
options.method = 'PUT'
|
|
194
|
+
return this.fetch(options)
|
|
192
195
|
}
|
|
193
196
|
|
|
194
197
|
/**
|
|
@@ -201,7 +204,9 @@ export default class Request
|
|
|
201
204
|
*/
|
|
202
205
|
patch(options)
|
|
203
206
|
{
|
|
204
|
-
|
|
207
|
+
options = this.#normalizeOptions(options)
|
|
208
|
+
options.method = 'PATCH'
|
|
209
|
+
return this.fetch(options)
|
|
205
210
|
}
|
|
206
211
|
|
|
207
212
|
/**
|
|
@@ -213,7 +218,9 @@ export default class Request
|
|
|
213
218
|
*/
|
|
214
219
|
delete(options)
|
|
215
220
|
{
|
|
216
|
-
|
|
221
|
+
options = this.#normalizeOptions(options)
|
|
222
|
+
options.method = 'DELETE'
|
|
223
|
+
return this.fetch(options)
|
|
217
224
|
}
|
|
218
225
|
|
|
219
226
|
/**
|
|
@@ -226,7 +233,9 @@ export default class Request
|
|
|
226
233
|
*/
|
|
227
234
|
head(options)
|
|
228
235
|
{
|
|
229
|
-
|
|
236
|
+
options = this.#normalizeOptions(options)
|
|
237
|
+
options.method = 'HEAD'
|
|
238
|
+
return this.fetch(options)
|
|
230
239
|
}
|
|
231
240
|
|
|
232
241
|
/**
|
|
@@ -239,7 +248,9 @@ export default class Request
|
|
|
239
248
|
*/
|
|
240
249
|
options(options)
|
|
241
250
|
{
|
|
242
|
-
|
|
251
|
+
options = this.#normalizeOptions(options)
|
|
252
|
+
options.method = 'OPTIONS'
|
|
253
|
+
return this.fetch(options)
|
|
243
254
|
}
|
|
244
255
|
|
|
245
256
|
/**
|
|
@@ -254,17 +265,19 @@ export default class Request
|
|
|
254
265
|
*/
|
|
255
266
|
trace(options)
|
|
256
267
|
{
|
|
257
|
-
|
|
268
|
+
options = this.#normalizeOptions(options)
|
|
269
|
+
options.method = 'TRACE'
|
|
270
|
+
return this.fetch(options)
|
|
258
271
|
}
|
|
259
272
|
|
|
260
273
|
/**
|
|
261
274
|
* Generic fetch method.
|
|
262
275
|
*
|
|
263
|
-
* @param {string} method
|
|
264
276
|
* @param {RequestOptions} options
|
|
265
277
|
*
|
|
266
278
|
* @returns {RequestResponse}
|
|
267
279
|
*
|
|
280
|
+
* @throws {TypeError} E_HTTP_REQUEST_INVALID_METHOD
|
|
268
281
|
* @throws {Error} E_HTTP_REQUEST_CLIENT_ERROR
|
|
269
282
|
* @throws {Error} E_HTTP_REQUEST_CLIENT_TIMEOUT
|
|
270
283
|
* @throws {Error} E_HTTP_REQUEST_DOWNSTREAM_ERROR
|
|
@@ -275,23 +288,11 @@ export default class Request
|
|
|
275
288
|
* @throws {Error} E_HTTP_REQUEST_RETRY_HTTP2_RECONNECT
|
|
276
289
|
* @throws {Error} E_HTTP_REQUEST_RETRY_ERROR
|
|
277
290
|
*/
|
|
278
|
-
async
|
|
291
|
+
async fetch(options)
|
|
279
292
|
{
|
|
280
|
-
|
|
281
|
-
{
|
|
282
|
-
options = { url:options }
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if(this.config.url && options.url)
|
|
286
|
-
{
|
|
287
|
-
options.url = options.url[0] === '/'
|
|
288
|
-
? options.url
|
|
289
|
-
: this.config.url + options.url
|
|
290
|
-
}
|
|
291
|
-
|
|
293
|
+
options = this.#normalizeOptions(options)
|
|
292
294
|
options = Object.assign(
|
|
293
295
|
{
|
|
294
|
-
method,
|
|
295
296
|
headers : {},
|
|
296
297
|
retry : 3,
|
|
297
298
|
retryDelay : 200,
|
|
@@ -300,6 +301,15 @@ export default class Request
|
|
|
300
301
|
retryOnStatus : []
|
|
301
302
|
}, this.config, options)
|
|
302
303
|
|
|
304
|
+
if('string' !== typeof options.method)
|
|
305
|
+
{
|
|
306
|
+
const error = new TypeError(`Method must be a string, got ${typeof options.method}`)
|
|
307
|
+
error.code = 'E_HTTP_REQUEST_INVALID_METHOD'
|
|
308
|
+
throw error
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
options.method = options.method.toUpperCase()
|
|
312
|
+
|
|
303
313
|
try
|
|
304
314
|
{
|
|
305
315
|
return options.retry
|
|
@@ -308,13 +318,23 @@ export default class Request
|
|
|
308
318
|
}
|
|
309
319
|
catch(reason)
|
|
310
320
|
{
|
|
311
|
-
const error = new Error(`Failed request ${method} ${options.url}`)
|
|
321
|
+
const error = new Error(`Failed request ${options.method} ${options.url}`)
|
|
312
322
|
error.code = 'E_HTTP_REQUEST_FAILED'
|
|
313
323
|
error.cause = reason
|
|
314
324
|
throw error
|
|
315
325
|
}
|
|
316
326
|
}
|
|
317
327
|
|
|
328
|
+
#normalizeOptions(options)
|
|
329
|
+
{
|
|
330
|
+
if(typeof options === 'string')
|
|
331
|
+
{
|
|
332
|
+
options = { url:options }
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return options
|
|
336
|
+
}
|
|
337
|
+
|
|
318
338
|
/**
|
|
319
339
|
* Resolves the request.
|
|
320
340
|
*
|
|
@@ -325,20 +345,20 @@ export default class Request
|
|
|
325
345
|
*/
|
|
326
346
|
#resolve(options)
|
|
327
347
|
{
|
|
328
|
-
return new Promise((
|
|
348
|
+
return new Promise((resolve, reject) =>
|
|
329
349
|
{
|
|
330
350
|
const
|
|
331
351
|
method = options.method,
|
|
332
352
|
headers = this.#normalizeHeaders(options.headers),
|
|
333
353
|
body = this.#normalizeBody(options.body ?? options.data, headers['content-type']),
|
|
334
354
|
delimiter = this.#createBodyHeaderDelimiter(body, !!options.upstream || !!this.http2Session),
|
|
335
|
-
url = this.#normalizeUrl(options.
|
|
355
|
+
url = this.#normalizeUrl(options.authority, options.base, options.url)
|
|
336
356
|
|
|
337
357
|
Object.assign(headers, delimiter)
|
|
338
358
|
|
|
339
359
|
const upstream = this.http2Session
|
|
340
|
-
? this.#resolveHttp2Client(options, method, headers, url,
|
|
341
|
-
: this.#resolveHttp1Client(options, method, headers, url,
|
|
360
|
+
? this.#resolveHttp2Client(options, method, headers, url, resolve, reject)
|
|
361
|
+
: this.#resolveHttp1Client(options, method, headers, url, resolve, reject)
|
|
342
362
|
|
|
343
363
|
options.upstream
|
|
344
364
|
? options.upstream.pipe(upstream)
|
|
@@ -346,7 +366,7 @@ export default class Request
|
|
|
346
366
|
})
|
|
347
367
|
}
|
|
348
368
|
|
|
349
|
-
#resolveHttp2Client(options, method, headers, url,
|
|
369
|
+
#resolveHttp2Client(options, method, headers, url, resolve, reject)
|
|
350
370
|
{
|
|
351
371
|
if(true === this.http2Session.destroyed)
|
|
352
372
|
{
|
|
@@ -394,13 +414,13 @@ export default class Request
|
|
|
394
414
|
delete upstream.headers[HEADER_STATUS]
|
|
395
415
|
Object.defineProperty(upstream.headers, SENSITIVE_HEADERS, { enumerable:false, value:headers[SENSITIVE_HEADERS] })
|
|
396
416
|
|
|
397
|
-
this.#resolveOnResponse(options, method, url,
|
|
417
|
+
this.#resolveOnResponse(options, method, url, resolve, reject, upstream)
|
|
398
418
|
})
|
|
399
419
|
|
|
400
420
|
return upstream
|
|
401
421
|
}
|
|
402
422
|
|
|
403
|
-
#resolveHttp1Client(options, method, headers, url,
|
|
423
|
+
#resolveHttp1Client(options, method, headers, url, resolve, reject)
|
|
404
424
|
{
|
|
405
425
|
const
|
|
406
426
|
request = url.startsWith('https:') ? https.request : http.request,
|
|
@@ -410,7 +430,7 @@ export default class Request
|
|
|
410
430
|
upstream.on('close', this.#connectionClosed .bind(this, upstream, reject))
|
|
411
431
|
upstream.on('error', this.#resolveOnClientError .bind(this, method, url, reject))
|
|
412
432
|
upstream.on('timeout', this.#resolveOnClientTimeout.bind(this, upstream, options.timeout, method, url, reject))
|
|
413
|
-
upstream.on('response', this.#resolveOnResponse .bind(this, options, method, url,
|
|
433
|
+
upstream.on('response', this.#resolveOnResponse .bind(this, options, method, url, resolve, reject))
|
|
414
434
|
|
|
415
435
|
return upstream
|
|
416
436
|
}
|
|
@@ -429,13 +449,13 @@ export default class Request
|
|
|
429
449
|
* @param {RequestOptions} options
|
|
430
450
|
* @param {String} method
|
|
431
451
|
* @param {String} url
|
|
432
|
-
* @param {Function}
|
|
452
|
+
* @param {Function} resolve Promise resolve
|
|
433
453
|
* @param {Function} reject Promise reject
|
|
434
454
|
* @param {http.IncomingMessage} readable
|
|
435
455
|
*
|
|
436
456
|
* @returns {Void}
|
|
437
457
|
*/
|
|
438
|
-
#resolveOnResponse(options, method, url,
|
|
458
|
+
#resolveOnResponse(options, method, url, resolve, reject, readable)
|
|
439
459
|
{
|
|
440
460
|
const response =
|
|
441
461
|
{
|
|
@@ -458,11 +478,11 @@ export default class Request
|
|
|
458
478
|
{
|
|
459
479
|
readable.pipe(options.downstream)
|
|
460
480
|
readable.resume()
|
|
461
|
-
|
|
481
|
+
resolve(response)
|
|
462
482
|
}
|
|
463
483
|
else
|
|
464
484
|
{
|
|
465
|
-
this.#bufferResponseBody(readable, response, method, url,
|
|
485
|
+
this.#bufferResponseBody(readable, response, method, url, resolve, reject)
|
|
466
486
|
}
|
|
467
487
|
}
|
|
468
488
|
|
|
@@ -509,19 +529,16 @@ export default class Request
|
|
|
509
529
|
}
|
|
510
530
|
}
|
|
511
531
|
|
|
512
|
-
const
|
|
513
|
-
|
|
514
|
-
reason
|
|
532
|
+
const
|
|
533
|
+
unique = reasons.filter((reason, i) => [i, -1].includes(reasons.map(e => e.code).lastIndexOf(code => code === reason.code))),
|
|
534
|
+
reason = unique.pop()
|
|
515
535
|
|
|
516
|
-
if(
|
|
536
|
+
if(unique.length)
|
|
517
537
|
{
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
else
|
|
521
|
-
{
|
|
522
|
-
reason.previous = uniqueReasons
|
|
523
|
-
throw reason
|
|
538
|
+
reason.retried = unique
|
|
524
539
|
}
|
|
540
|
+
|
|
541
|
+
throw reason
|
|
525
542
|
}
|
|
526
543
|
|
|
527
544
|
/**
|
|
@@ -662,17 +679,28 @@ export default class Request
|
|
|
662
679
|
|
|
663
680
|
/**
|
|
664
681
|
* Normalizes the URL.
|
|
682
|
+
* One of authority or base must be provided,
|
|
665
683
|
*
|
|
666
|
-
* @param {String}
|
|
667
|
-
* @param {String}
|
|
684
|
+
* @param {String} [base]
|
|
685
|
+
* @param {String} [authority] the URL origin (e.g. https://example.com)
|
|
686
|
+
* @param {String} [url]
|
|
668
687
|
*
|
|
669
688
|
* @returns {String} Normalized URL
|
|
670
689
|
*/
|
|
671
|
-
#normalizeUrl(
|
|
690
|
+
#normalizeUrl(authority, base, url)
|
|
672
691
|
{
|
|
692
|
+
let baseURL = authority && base
|
|
693
|
+
? new URL(base, authority)
|
|
694
|
+
: new URL(base || authority)
|
|
695
|
+
|
|
696
|
+
if(url && false === baseURL.pathname.endsWith('/'))
|
|
697
|
+
{
|
|
698
|
+
baseURL = new URL(baseURL.pathname + '/', baseURL.href)
|
|
699
|
+
}
|
|
700
|
+
|
|
673
701
|
return url
|
|
674
|
-
? new URL(url,
|
|
675
|
-
:
|
|
702
|
+
? new URL(url, baseURL.href).href
|
|
703
|
+
: baseURL.href
|
|
676
704
|
}
|
|
677
705
|
|
|
678
706
|
/**
|
|
@@ -723,12 +751,12 @@ export default class Request
|
|
|
723
751
|
upstream.destroy(error)
|
|
724
752
|
}
|
|
725
753
|
|
|
726
|
-
#bufferResponseBody(readable, response, method, url,
|
|
754
|
+
#bufferResponseBody(readable, response, method, url, resolve, reject)
|
|
727
755
|
{
|
|
728
756
|
response.body = ''
|
|
729
757
|
readable.on('data', (chunk) => response.body += chunk)
|
|
730
758
|
readable.on('error', this.#onStreamError.bind(this, method, url, response))
|
|
731
|
-
readable.on('end', this.#onStreamEnd .bind(this, method, url, response,
|
|
759
|
+
readable.on('end', this.#onStreamEnd .bind(this, method, url, response, resolve, reject))
|
|
732
760
|
readable.resume()
|
|
733
761
|
}
|
|
734
762
|
|
|
@@ -759,14 +787,14 @@ export default class Request
|
|
|
759
787
|
* @param {String} method
|
|
760
788
|
* @param {String} url
|
|
761
789
|
* @param {http.IncomingMessage} response
|
|
762
|
-
* @param {Function}
|
|
790
|
+
* @param {Function} resolve promise resolve
|
|
763
791
|
* @param {Function} reject promise reject
|
|
764
792
|
*
|
|
765
793
|
* @returns {void}
|
|
766
794
|
*
|
|
767
795
|
* @throws {Error} E_HTTP_REQUEST_INVALID_RESPONSE_BODY_FORMAT
|
|
768
796
|
*/
|
|
769
|
-
#onStreamEnd(method, url, response,
|
|
797
|
+
#onStreamEnd(method, url, response, resolve, reject)
|
|
770
798
|
{
|
|
771
799
|
try
|
|
772
800
|
{
|
|
@@ -791,7 +819,7 @@ export default class Request
|
|
|
791
819
|
return
|
|
792
820
|
}
|
|
793
821
|
|
|
794
|
-
|
|
822
|
+
resolve(response)
|
|
795
823
|
}
|
|
796
824
|
|
|
797
825
|
#contentTypeApplicationJson(body)
|
package/index.test.js
CHANGED
|
@@ -53,6 +53,50 @@ suite('@superhero/http-request', () =>
|
|
|
53
53
|
assert.equal(response.body.url, '/', 'Should result to /')
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
+
test('Request using a relative path', async sub =>
|
|
57
|
+
{
|
|
58
|
+
// ...close the server that was started before the
|
|
59
|
+
// sub tests starts another server for each test...
|
|
60
|
+
await request.close()
|
|
61
|
+
await new Promise(resolve => server.close(resolve))
|
|
62
|
+
|
|
63
|
+
await sub.test('Request using an absolute path with a trailing base path slash', async () =>
|
|
64
|
+
{
|
|
65
|
+
const base = request.config.base || ''
|
|
66
|
+
request.config.base = base + '/path/'
|
|
67
|
+
const response = await request.get('/foobar')
|
|
68
|
+
assert.equal(response.status, 200, 'Should return a 200 status code')
|
|
69
|
+
assert.equal(response.body.url, '/foobar', 'Should result to the absolute path')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
await sub.test('Request using a absolute path with out a trailing base path slash', async () =>
|
|
73
|
+
{
|
|
74
|
+
const base = request.config.base || ''
|
|
75
|
+
request.config.base = base + '/path'
|
|
76
|
+
const response = await request.get('/foobar')
|
|
77
|
+
assert.equal(response.status, 200, 'Should return a 200 status code')
|
|
78
|
+
assert.equal(response.body.url, '/foobar', 'Should result to the absolute path')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
await sub.test('Request using a relative path with a trailing base path slash', async () =>
|
|
82
|
+
{
|
|
83
|
+
const base = request.config.base || ''
|
|
84
|
+
request.config.base = base + '/path/'
|
|
85
|
+
const response = await request.get('foobar')
|
|
86
|
+
assert.equal(response.status, 200, 'Should return a 200 status code')
|
|
87
|
+
assert.equal(response.body.url, '/path/foobar', 'Should result to the absolute path')
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
await sub.test('Request using a relative path with out a trailing base path slash', async () =>
|
|
91
|
+
{
|
|
92
|
+
const base = request.config.base || ''
|
|
93
|
+
request.config.base = base + '/path'
|
|
94
|
+
const response = await request.get('foobar')
|
|
95
|
+
assert.equal(response.status, 200, 'Should return a 200 status code')
|
|
96
|
+
assert.equal(response.body.url, '/path/foobar', 'Should result to the absolute path')
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
56
100
|
test('Request using a string body', async () =>
|
|
57
101
|
{
|
|
58
102
|
const response = await request.post({ body: 'test body' })
|
|
@@ -503,7 +547,7 @@ suite('@superhero/http-request', () =>
|
|
|
503
547
|
})
|
|
504
548
|
})
|
|
505
549
|
|
|
506
|
-
afterEach(
|
|
550
|
+
afterEach(done => request.close().then(() => server.close(done)))
|
|
507
551
|
|
|
508
552
|
executeTheSameTestSuitFor_http1_http2()
|
|
509
553
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superhero/http-request",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"description": "HTTP(S) request component supporting HTTP 1.1 and HTTP 2.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"http request",
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
".": "./index.js"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "node --
|
|
21
|
+
"test": "node --test --test-reporter=@superhero/audit/reporter --experimental-test-coverage"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@superhero/audit": "^4.0.3"
|
|
22
25
|
},
|
|
23
26
|
"author": {
|
|
24
27
|
"name": "Erik Landvall",
|