@mswjs/interceptors 0.22.2 → 0.22.3

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.
@@ -3,7 +3,7 @@
3
3
  var _chunkQ56TMOP5js = require('./chunk-Q56TMOP5.js');
4
4
 
5
5
 
6
- var _chunkPRX3F52Mjs = require('./chunk-PRX3F52M.js');
6
+ var _chunkXLZJAPVSjs = require('./chunk-XLZJAPVS.js');
7
7
 
8
8
 
9
9
  var _chunkGGD5JOGBjs = require('./chunk-GGD5JOGB.js');
@@ -23,7 +23,7 @@ var RemoteHttpInterceptor = class extends _chunkQ56TMOP5js.BatchInterceptor {
23
23
  super({
24
24
  name: "remote-interceptor",
25
25
  interceptors: [
26
- new (0, _chunkPRX3F52Mjs.ClientRequestInterceptor)(),
26
+ new (0, _chunkXLZJAPVSjs.ClientRequestInterceptor)(),
27
27
  new (0, _chunkGGD5JOGBjs.XMLHttpRequestInterceptor)()
28
28
  ]
29
29
  });
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KZEQH4YW.mjs";
4
4
  import {
5
5
  ClientRequestInterceptor
6
- } from "./chunk-SWJ33XIS.mjs";
6
+ } from "./chunk-FGPCRIW6.mjs";
7
7
  import {
8
8
  XMLHttpRequestInterceptor
9
9
  } from "./chunk-CYWTKHFI.mjs";
@@ -404,7 +404,6 @@ var debug3 = __require("debug")("utils getUrlByRequestOptions");
404
404
  var DEFAULT_PATH = "/";
405
405
  var DEFAULT_PROTOCOL = "http:";
406
406
  var DEFAULT_HOST = "localhost";
407
- var DEFAULT_PORT = 80;
408
407
  var SSL_PORT = 443;
409
408
  function getAgent(options) {
410
409
  return options.agent instanceof Agent ? options.agent : void 0;
@@ -424,16 +423,30 @@ function getProtocolByRequestOptions(options) {
424
423
  return isSecureRequest ? "https:" : ((_a = options.uri) == null ? void 0 : _a.protocol) || DEFAULT_PROTOCOL;
425
424
  }
426
425
  function getPortByRequestOptions(options) {
426
+ if (options.port) {
427
+ return Number(options.port);
428
+ }
429
+ if (options.hostname != null) {
430
+ const [, extractedPort] = options.hostname.match(/:(\d+)$/) || [];
431
+ if (extractedPort != null) {
432
+ return Number(extractedPort);
433
+ }
434
+ }
427
435
  const agent = getAgent(options);
428
- const agentPort = (agent == null ? void 0 : agent.options.port) || (agent == null ? void 0 : agent.defaultPort);
429
- const optionsPort = options.port;
430
- if (optionsPort || agentPort) {
431
- const explicitPort = optionsPort || agentPort || DEFAULT_PORT;
432
- return Number(explicitPort);
436
+ if (agent == null ? void 0 : agent.options.port) {
437
+ return Number(agent.options.port);
438
+ }
439
+ if (agent == null ? void 0 : agent.defaultPort) {
440
+ return Number(agent.defaultPort);
433
441
  }
442
+ return void 0;
434
443
  }
435
444
  function getHostByRequestOptions(options) {
436
- return options.hostname || options.host || DEFAULT_HOST;
445
+ const { hostname, host } = options;
446
+ if (hostname != null) {
447
+ return hostname.replace(/:\d+$/, "");
448
+ }
449
+ return host || DEFAULT_HOST;
437
450
  }
438
451
  function getAuthByRequestOptions(options) {
439
452
  if (options.auth) {
@@ -444,30 +457,42 @@ function getAuthByRequestOptions(options) {
444
457
  function isRawIPv6Address(host) {
445
458
  return host.includes(":") && !host.startsWith("[") && !host.endsWith("]");
446
459
  }
460
+ function getHostname(host, port) {
461
+ const portString = typeof port !== "undefined" ? `:${port}` : "";
462
+ if (isRawIPv6Address(host)) {
463
+ return `[${host}]${portString}`;
464
+ }
465
+ if (typeof port === "undefined") {
466
+ return host;
467
+ }
468
+ return `${host}${portString}`;
469
+ }
447
470
  function getUrlByRequestOptions(options) {
448
471
  debug3("request options", options);
472
+ if (options.uri) {
473
+ debug3(
474
+ 'constructing url from explicitly provided "options.uri": %s',
475
+ options.uri
476
+ );
477
+ return new URL(options.uri.href);
478
+ }
479
+ debug3("figuring out url from request options...");
449
480
  const protocol = getProtocolByRequestOptions(options);
450
- const host = getHostByRequestOptions(options);
451
- const port = getPortByRequestOptions(options);
452
- const path = options.path || DEFAULT_PATH;
453
- const auth = getAuthByRequestOptions(options);
454
481
  debug3("protocol", protocol);
482
+ const host = getHostByRequestOptions(options);
455
483
  debug3("host", host);
484
+ const port = getPortByRequestOptions(options);
456
485
  debug3("port", port);
486
+ const hostname = getHostname(host, port);
487
+ debug3("hostname", hostname);
488
+ const path = options.path || DEFAULT_PATH;
457
489
  debug3("path", path);
458
- const baseUrl = `${protocol}//${isRawIPv6Address(host) ? `[${host}]` : host}`;
459
- debug3("base URL:", baseUrl);
460
- const url = options.uri ? new URL(options.uri.href) : new URL(path, baseUrl);
461
- if (port) {
462
- debug3("detected explicit port", port);
463
- url.port = port.toString();
464
- }
465
- if (auth) {
466
- debug3("resolved auth", auth);
467
- url.username = auth.username;
468
- url.password = auth.password;
469
- }
470
- debug3("created URL:", url);
490
+ const credentials = getAuthByRequestOptions(options);
491
+ debug3("credentials", credentials);
492
+ const authString = credentials ? `${credentials.username}:${credentials.password}@` : "";
493
+ debug3("auth string:", authString);
494
+ const url = new URL(`${protocol}//${authString}${hostname}${path}`);
495
+ debug3("created url:", url);
471
496
  return url;
472
497
  }
473
498
 
@@ -404,7 +404,6 @@ var debug3 = _chunkWWHITCCIjs.__require.call(void 0, "debug")("utils getUrlByReq
404
404
  var DEFAULT_PATH = "/";
405
405
  var DEFAULT_PROTOCOL = "http:";
406
406
  var DEFAULT_HOST = "localhost";
407
- var DEFAULT_PORT = 80;
408
407
  var SSL_PORT = 443;
409
408
  function getAgent(options) {
410
409
  return options.agent instanceof _http.Agent ? options.agent : void 0;
@@ -424,16 +423,30 @@ function getProtocolByRequestOptions(options) {
424
423
  return isSecureRequest ? "https:" : ((_a = options.uri) == null ? void 0 : _a.protocol) || DEFAULT_PROTOCOL;
425
424
  }
426
425
  function getPortByRequestOptions(options) {
426
+ if (options.port) {
427
+ return Number(options.port);
428
+ }
429
+ if (options.hostname != null) {
430
+ const [, extractedPort] = options.hostname.match(/:(\d+)$/) || [];
431
+ if (extractedPort != null) {
432
+ return Number(extractedPort);
433
+ }
434
+ }
427
435
  const agent = getAgent(options);
428
- const agentPort = (agent == null ? void 0 : agent.options.port) || (agent == null ? void 0 : agent.defaultPort);
429
- const optionsPort = options.port;
430
- if (optionsPort || agentPort) {
431
- const explicitPort = optionsPort || agentPort || DEFAULT_PORT;
432
- return Number(explicitPort);
436
+ if (agent == null ? void 0 : agent.options.port) {
437
+ return Number(agent.options.port);
438
+ }
439
+ if (agent == null ? void 0 : agent.defaultPort) {
440
+ return Number(agent.defaultPort);
433
441
  }
442
+ return void 0;
434
443
  }
435
444
  function getHostByRequestOptions(options) {
436
- return options.hostname || options.host || DEFAULT_HOST;
445
+ const { hostname, host } = options;
446
+ if (hostname != null) {
447
+ return hostname.replace(/:\d+$/, "");
448
+ }
449
+ return host || DEFAULT_HOST;
437
450
  }
438
451
  function getAuthByRequestOptions(options) {
439
452
  if (options.auth) {
@@ -444,30 +457,42 @@ function getAuthByRequestOptions(options) {
444
457
  function isRawIPv6Address(host) {
445
458
  return host.includes(":") && !host.startsWith("[") && !host.endsWith("]");
446
459
  }
460
+ function getHostname(host, port) {
461
+ const portString = typeof port !== "undefined" ? `:${port}` : "";
462
+ if (isRawIPv6Address(host)) {
463
+ return `[${host}]${portString}`;
464
+ }
465
+ if (typeof port === "undefined") {
466
+ return host;
467
+ }
468
+ return `${host}${portString}`;
469
+ }
447
470
  function getUrlByRequestOptions(options) {
448
471
  debug3("request options", options);
472
+ if (options.uri) {
473
+ debug3(
474
+ 'constructing url from explicitly provided "options.uri": %s',
475
+ options.uri
476
+ );
477
+ return new URL(options.uri.href);
478
+ }
479
+ debug3("figuring out url from request options...");
449
480
  const protocol = getProtocolByRequestOptions(options);
450
- const host = getHostByRequestOptions(options);
451
- const port = getPortByRequestOptions(options);
452
- const path = options.path || DEFAULT_PATH;
453
- const auth = getAuthByRequestOptions(options);
454
481
  debug3("protocol", protocol);
482
+ const host = getHostByRequestOptions(options);
455
483
  debug3("host", host);
484
+ const port = getPortByRequestOptions(options);
456
485
  debug3("port", port);
486
+ const hostname = getHostname(host, port);
487
+ debug3("hostname", hostname);
488
+ const path = options.path || DEFAULT_PATH;
457
489
  debug3("path", path);
458
- const baseUrl = `${protocol}//${isRawIPv6Address(host) ? `[${host}]` : host}`;
459
- debug3("base URL:", baseUrl);
460
- const url = options.uri ? new URL(options.uri.href) : new URL(path, baseUrl);
461
- if (port) {
462
- debug3("detected explicit port", port);
463
- url.port = port.toString();
464
- }
465
- if (auth) {
466
- debug3("resolved auth", auth);
467
- url.username = auth.username;
468
- url.password = auth.password;
469
- }
470
- debug3("created URL:", url);
490
+ const credentials = getAuthByRequestOptions(options);
491
+ debug3("credentials", credentials);
492
+ const authString = credentials ? `${credentials.username}:${credentials.password}@` : "";
493
+ debug3("auth string:", authString);
494
+ const url = new URL(`${protocol}//${authString}${hostname}${path}`);
495
+ debug3("created url:", url);
471
496
  return url;
472
497
  }
473
498
 
@@ -1,8 +1,8 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkPRX3F52Mjs = require('../../chunk-PRX3F52M.js');
3
+ var _chunkXLZJAPVSjs = require('../../chunk-XLZJAPVS.js');
4
4
  require('../../chunk-ZJOF5MEZ.js');
5
5
  require('../../chunk-WWHITCCI.js');
6
6
 
7
7
 
8
- exports.ClientRequestInterceptor = _chunkPRX3F52Mjs.ClientRequestInterceptor;
8
+ exports.ClientRequestInterceptor = _chunkXLZJAPVSjs.ClientRequestInterceptor;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ClientRequestInterceptor
3
- } from "../../chunk-SWJ33XIS.mjs";
3
+ } from "../../chunk-FGPCRIW6.mjs";
4
4
  import "../../chunk-STA6QBYM.mjs";
5
5
  import "../../chunk-37CATPNG.mjs";
6
6
  export {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mswjs/interceptors",
3
3
  "description": "Low-level HTTP/HTTPS/XHR/fetch request interception library.",
4
- "version": "0.22.2",
4
+ "version": "0.22.3",
5
5
  "main": "./lib/node/index.js",
6
6
  "module": "./lib/node/index.mjs",
7
7
  "types": "./lib/node/index.d.ts",
@@ -4,138 +4,132 @@ import { RequestOptions, Agent as HttpsAgent } from 'https'
4
4
  import { getUrlByRequestOptions } from './getUrlByRequestOptions'
5
5
 
6
6
  it('returns a URL based on the basic RequestOptions', () => {
7
- const options: RequestOptions = {
8
- protocol: 'https:',
9
- host: '127.0.0.1',
10
- path: '/resource',
11
- }
12
- const url = getUrlByRequestOptions(options)
13
-
14
- expect(url).toBeInstanceOf(URL)
15
- expect(url).toHaveProperty('port', '')
16
- expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
7
+ expect(
8
+ getUrlByRequestOptions({
9
+ protocol: 'https:',
10
+ host: '127.0.0.1',
11
+ path: '/resource',
12
+ }).href
13
+ ).toBe('https://127.0.0.1/resource')
17
14
  })
18
15
 
19
16
  it('inherits protocol and port from http.Agent, if set', () => {
20
- const options: RequestOptions = {
21
- host: '127.0.0.1',
22
- path: '/',
23
- agent: new HttpAgent(),
24
- }
25
- const url = getUrlByRequestOptions(options)
26
-
27
- expect(url).toBeInstanceOf(URL)
28
- expect(url).toHaveProperty('protocol', 'http:')
29
- expect(url).toHaveProperty('port', '')
30
- expect(url).toHaveProperty('href', 'http://127.0.0.1/')
17
+ expect(
18
+ getUrlByRequestOptions({
19
+ host: '127.0.0.1',
20
+ path: '/',
21
+ agent: new HttpAgent(),
22
+ }).href
23
+ ).toBe('http://127.0.0.1/')
31
24
  })
32
25
 
33
26
  it('inherits protocol and port from https.Agent, if set', () => {
34
- const options: RequestOptions = {
35
- host: '127.0.0.1',
36
- path: '/',
37
- agent: new HttpsAgent({
38
- port: 3080,
39
- }),
40
- }
41
- const url = getUrlByRequestOptions(options)
42
-
43
- expect(url).toBeInstanceOf(URL)
44
- expect(url).toHaveProperty('protocol', 'https:')
45
- expect(url).toHaveProperty('port', '3080')
46
- expect(url).toHaveProperty('href', 'https://127.0.0.1:3080/')
27
+ expect(
28
+ getUrlByRequestOptions({
29
+ host: '127.0.0.1',
30
+ path: '/',
31
+ agent: new HttpsAgent({
32
+ port: 3080,
33
+ }),
34
+ }).href
35
+ ).toBe('https://127.0.0.1:3080/')
47
36
  })
48
37
 
49
38
  it('resolves protocol to "http" given no explicit protocol and no certificate', () => {
50
- const options: RequestOptions = {
51
- host: '127.0.0.1',
52
- path: '/',
53
- }
54
- const url = getUrlByRequestOptions(options)
55
-
56
- expect(url).toBeInstanceOf(URL)
57
- expect(url).toHaveProperty('protocol', 'http:')
58
- expect(url).toHaveProperty('port', '')
59
- expect(url).toHaveProperty('href', 'http://127.0.0.1/')
39
+ expect(
40
+ getUrlByRequestOptions({
41
+ host: '127.0.0.1',
42
+ path: '/',
43
+ }).href
44
+ ).toBe('http://127.0.0.1/')
60
45
  })
61
46
 
62
47
  it('resolves protocol to "https" given no explicit protocol, but certificate', () => {
63
- const options: RequestOptions = {
64
- host: '127.0.0.1',
65
- path: '/secure',
66
- cert: '<!-- SSL certificate -->',
67
- }
68
- const url = getUrlByRequestOptions(options)
69
-
70
- expect(url).toBeInstanceOf(URL)
71
- expect(url).toHaveProperty('protocol', 'https:')
72
- expect(url).toHaveProperty('port', '')
73
- expect(url).toHaveProperty('href', 'https://127.0.0.1/secure')
48
+ expect(
49
+ getUrlByRequestOptions({
50
+ host: '127.0.0.1',
51
+ path: '/secure',
52
+ cert: '<!-- SSL certificate -->',
53
+ }).href
54
+ ).toBe('https://127.0.0.1/secure')
74
55
  })
75
56
 
76
57
  it('resolves protocol to "https" given no explicit protocol, but port is 443', () => {
77
- const options: RequestOptions = {
78
- host: '127.0.0.1',
79
- port: 443,
80
- path: '/resource',
81
- }
82
- const url = getUrlByRequestOptions(options)
83
-
84
- expect(url).toBeInstanceOf(URL)
85
- expect(url).toHaveProperty('port', '')
86
- expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
58
+ expect(
59
+ getUrlByRequestOptions({
60
+ host: '127.0.0.1',
61
+ port: 443,
62
+ path: '/resource',
63
+ }).href
64
+ ).toBe('https://127.0.0.1/resource')
87
65
  })
88
66
 
89
67
  it('resolves protocol to "https" given no explicit protocol, but agent port is 443', () => {
90
- const options: RequestOptions = {
91
- host: '127.0.0.1',
92
- agent: new HttpsAgent({
93
- port: 443,
94
- }),
95
- path: '/resource',
96
- }
97
- const url = getUrlByRequestOptions(options)
98
-
99
- expect(url).toBeInstanceOf(URL)
100
- expect(url).toHaveProperty('port', '')
101
- expect(url).toHaveProperty('href', 'https://127.0.0.1/resource')
68
+ expect(
69
+ getUrlByRequestOptions({
70
+ host: '127.0.0.1',
71
+ agent: new HttpsAgent({
72
+ port: 443,
73
+ }),
74
+ path: '/resource',
75
+ }).href
76
+ ).toBe('https://127.0.0.1/resource')
102
77
  })
103
78
 
104
- it('inherits "port" if given', () => {
105
- const options = {
106
- protocol: 'http:',
107
- host: '127.0.0.1',
108
- port: 4002,
109
- path: '/',
110
- }
111
- const url = getUrlByRequestOptions(options)
112
-
113
- expect(url).toBeInstanceOf(URL)
114
- expect(url).toHaveProperty('port', '4002')
115
- expect(url).toHaveProperty('protocol', 'http:')
116
- expect(url).toHaveProperty('href', 'http://127.0.0.1:4002/')
79
+ it('respects explicitly provided port', () => {
80
+ expect(
81
+ getUrlByRequestOptions({
82
+ protocol: 'http:',
83
+ host: '127.0.0.1',
84
+ port: 4002,
85
+ path: '/',
86
+ }).href
87
+ ).toBe('http://127.0.0.1:4002/')
117
88
  })
118
89
 
119
90
  it('inherits "username" and "password"', () => {
120
- const options: RequestOptions = {
91
+ const url = getUrlByRequestOptions({
121
92
  protocol: 'https:',
122
93
  host: '127.0.0.1',
123
94
  path: '/user',
124
95
  auth: 'admin:abc-123',
125
- }
126
- const url = getUrlByRequestOptions(options)
96
+ })
127
97
 
128
98
  expect(url).toBeInstanceOf(URL)
129
99
  expect(url).toHaveProperty('username', 'admin')
130
100
  expect(url).toHaveProperty('password', 'abc-123')
131
- expect(url).toHaveProperty('protocol', 'https:')
132
101
  expect(url).toHaveProperty('href', 'https://admin:abc-123@127.0.0.1/user')
133
102
  })
134
103
 
135
104
  it('resolves hostname to localhost if none provided', () => {
136
- const url = getUrlByRequestOptions({})
105
+ expect(getUrlByRequestOptions({}).hostname).toBe('localhost')
106
+ })
137
107
 
138
- expect(url).toBeInstanceOf(URL)
139
- expect(url).toHaveProperty('protocol', 'http:')
140
- expect(url).toHaveProperty('href', 'http://localhost/')
108
+ it('supports "hostname" instead of "host" and "port"', () => {
109
+ const options: RequestOptions = {
110
+ protocol: 'https:',
111
+ hostname: '127.0.0.1:1234',
112
+ path: '/resource',
113
+ }
114
+
115
+ expect(getUrlByRequestOptions(options).href).toBe(
116
+ 'https://127.0.0.1:1234/resource'
117
+ )
118
+ })
119
+
120
+ it('handles IPv6 hostnames', () => {
121
+ expect(
122
+ getUrlByRequestOptions({
123
+ host: '::1',
124
+ path: '/resource',
125
+ }).href
126
+ ).toBe('http://[::1]/resource')
127
+
128
+ expect(
129
+ getUrlByRequestOptions({
130
+ host: '::1',
131
+ port: 3001,
132
+ path: '/resource',
133
+ }).href
134
+ ).toBe('http://[::1]:3001/resource')
141
135
  })
@@ -15,7 +15,6 @@ export type ResolvedRequestOptions = RequestOptions & RequestSelf
15
15
  export const DEFAULT_PATH = '/'
16
16
  const DEFAULT_PROTOCOL = 'http:'
17
17
  const DEFAULT_HOST = 'localhost'
18
- const DEFAULT_PORT = 80
19
18
  const SSL_PORT = 443
20
19
 
21
20
  function getAgent(
@@ -45,20 +44,45 @@ function getProtocolByRequestOptions(options: ResolvedRequestOptions): string {
45
44
  function getPortByRequestOptions(
46
45
  options: ResolvedRequestOptions
47
46
  ): number | undefined {
47
+ // Use the explicitly provided port.
48
+ if (options.port) {
49
+ return Number(options.port)
50
+ }
51
+
52
+ // Extract the port from the hostname.
53
+ if (options.hostname != null) {
54
+ const [, extractedPort] = options.hostname.match(/:(\d+)$/) || []
55
+
56
+ if (extractedPort != null) {
57
+ return Number(extractedPort)
58
+ }
59
+ }
60
+
61
+ // Otherwise, try to resolve port from the agent.
48
62
  const agent = getAgent(options)
49
- const agentPort =
50
- (agent as HttpsAgent)?.options.port ||
51
- (agent as RequestOptions)?.defaultPort
52
- const optionsPort = options.port
53
-
54
- if (optionsPort || agentPort) {
55
- const explicitPort = optionsPort || agentPort || DEFAULT_PORT
56
- return Number(explicitPort)
63
+
64
+ if ((agent as HttpsAgent)?.options.port) {
65
+ return Number((agent as HttpsAgent).options.port)
57
66
  }
67
+
68
+ if ((agent as RequestOptions)?.defaultPort) {
69
+ return Number((agent as RequestOptions).defaultPort)
70
+ }
71
+
72
+ // Lastly, return undefined indicating that the port
73
+ // must inferred from the protocol. Do not infer it here.
74
+ return undefined
58
75
  }
59
76
 
60
77
  function getHostByRequestOptions(options: ResolvedRequestOptions): string {
61
- return options.hostname || options.host || DEFAULT_HOST
78
+ const { hostname, host } = options
79
+
80
+ // If the hostname is specified, resolve the host from the "host:port" string.
81
+ if (hostname != null) {
82
+ return hostname.replace(/:\d+$/, '')
83
+ }
84
+
85
+ return host || DEFAULT_HOST
62
86
  }
63
87
 
64
88
  function getAuthByRequestOptions(options: ResolvedRequestOptions) {
@@ -77,45 +101,65 @@ function isRawIPv6Address(host: string): boolean {
77
101
  return host.includes(':') && !host.startsWith('[') && !host.endsWith(']')
78
102
  }
79
103
 
104
+ function getHostname(host: string, port?: number): string {
105
+ const portString = typeof port !== 'undefined' ? `:${port}` : ''
106
+
107
+ /**
108
+ * @note As of Node >= 17, hosts (including "localhost") can resolve to IPv6
109
+ * addresses, so construct valid URL by surrounding the IPv6 host with brackets.
110
+ */
111
+ if (isRawIPv6Address(host)) {
112
+ return `[${host}]${portString}`
113
+ }
114
+
115
+ if (typeof port === 'undefined') {
116
+ return host
117
+ }
118
+
119
+ return `${host}${portString}`
120
+ }
121
+
80
122
  /**
81
123
  * Creates a `URL` instance from a given `RequestOptions` object.
82
124
  */
83
125
  export function getUrlByRequestOptions(options: ResolvedRequestOptions): URL {
84
126
  debug('request options', options)
85
127
 
86
- const protocol = getProtocolByRequestOptions(options)
87
- const host = getHostByRequestOptions(options)
88
- const port = getPortByRequestOptions(options)
89
- const path = options.path || DEFAULT_PATH
90
- const auth = getAuthByRequestOptions(options)
128
+ if (options.uri) {
129
+ debug(
130
+ 'constructing url from explicitly provided "options.uri": %s',
131
+ options.uri
132
+ )
133
+ return new URL(options.uri.href)
134
+ }
91
135
 
136
+ debug('figuring out url from request options...')
137
+
138
+ const protocol = getProtocolByRequestOptions(options)
92
139
  debug('protocol', protocol)
140
+
141
+ const host = getHostByRequestOptions(options)
93
142
  debug('host', host)
94
- debug('port', port)
95
- debug('path', path)
96
143
 
97
- /**
98
- * @note As of Node >= 17, hosts (including "localhost") can resolve to IPv6
99
- * addresses, so construct valid URL by surrounding the IPv6 host with brackets.
100
- */
101
- const baseUrl = `${protocol}//${isRawIPv6Address(host) ? `[${host}]` : host}`
102
- debug('base URL:', baseUrl)
144
+ const port = getPortByRequestOptions(options)
145
+ debug('port', port)
103
146
 
104
- const url = options.uri ? new URL(options.uri.href) : new URL(path, baseUrl)
147
+ const hostname = getHostname(host, port)
148
+ debug('hostname', hostname)
105
149
 
106
- if (port) {
107
- debug('detected explicit port', port)
108
- url.port = port.toString()
109
- }
150
+ const path = options.path || DEFAULT_PATH
151
+ debug('path', path)
110
152
 
111
- if (auth) {
112
- debug('resolved auth', auth)
153
+ const credentials = getAuthByRequestOptions(options)
154
+ debug('credentials', credentials)
113
155
 
114
- url.username = auth.username
115
- url.password = auth.password
116
- }
156
+ const authString = credentials
157
+ ? `${credentials.username}:${credentials.password}@`
158
+ : ''
159
+ debug('auth string:', authString)
117
160
 
118
- debug('created URL:', url)
161
+ const url = new URL(`${protocol}//${authString}${hostname}${path}`)
162
+ debug('created url:', url)
119
163
 
120
164
  return url
121
165
  }