source: frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/utils/getSocketUrlParts.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.7 KB
RevLine 
[9af201e]1const getCurrentScriptSource = require('./getCurrentScriptSource.js');
2
3/**
4 * @typedef {Object} SocketUrlParts
5 * @property {string} [auth]
6 * @property {string} hostname
7 * @property {string} [protocol]
8 * @property {string} pathname
9 * @property {string} [port]
10 */
11
12/**
13 * Parse current location and Webpack's `__resourceQuery` into parts that can create a valid socket URL.
14 * @param {string} [resourceQuery] The Webpack `__resourceQuery` string.
15 * @param {import('./getWDSMetadata').WDSMetaObj} [metadata] The parsed WDS metadata object.
16 * @returns {SocketUrlParts} The parsed URL parts.
17 * @see https://webpack.js.org/api/module-variables/#__resourcequery-webpack-specific
18 */
19function getSocketUrlParts(resourceQuery, metadata) {
20 if (typeof metadata === 'undefined') {
21 metadata = {};
22 }
23
24 /** @type {SocketUrlParts} */
25 let urlParts = {};
26
27 // If the resource query is available,
28 // parse it and ignore everything we received from the script host.
29 if (resourceQuery) {
30 const parsedQuery = {};
31 const searchParams = new URLSearchParams(resourceQuery.slice(1));
32 searchParams.forEach(function (value, key) {
33 parsedQuery[key] = value;
34 });
35
36 urlParts.hostname = parsedQuery.sockHost;
37 urlParts.pathname = parsedQuery.sockPath;
38 urlParts.port = parsedQuery.sockPort;
39
40 // Make sure the protocol from resource query has a trailing colon
41 if (parsedQuery.sockProtocol) {
42 urlParts.protocol = parsedQuery.sockProtocol + ':';
43 }
44 } else {
45 const scriptSource = getCurrentScriptSource();
46
47 let url = {};
48 try {
49 // The placeholder `baseURL` with `window.location.href`,
50 // is to allow parsing of path-relative or protocol-relative URLs,
51 // and will have no effect if `scriptSource` is a fully valid URL.
52 url = new URL(scriptSource, window.location.href);
53 } catch (e) {
54 // URL parsing failed, do nothing.
55 // We will still proceed to see if we can recover using `resourceQuery`
56 }
57
58 // Parse authentication credentials in case we need them
59 if (url.username) {
60 // Since HTTP basic authentication does not allow empty username,
61 // we only include password if the username is not empty.
62 // Result: <username> or <username>:<password>
63 urlParts.auth = url.username;
64 if (url.password) {
65 urlParts.auth += ':' + url.password;
66 }
67 }
68
69 // `file://` URLs has `'null'` origin
70 if (url.origin !== 'null') {
71 urlParts.hostname = url.hostname;
72 }
73
74 urlParts.protocol = url.protocol;
75 urlParts.port = url.port;
76 }
77
78 if (!urlParts.pathname) {
79 if (metadata.version === 4) {
80 // This is hard-coded in WDS v4
81 urlParts.pathname = '/ws';
82 } else {
83 // This is hard-coded in WDS v3
84 urlParts.pathname = '/sockjs-node';
85 }
86 }
87
88 // Check for IPv4 and IPv6 host addresses that correspond to any/empty.
89 // This is important because `hostname` can be empty for some hosts,
90 // such as 'about:blank' or 'file://' URLs.
91 const isEmptyHostname =
92 urlParts.hostname === '0.0.0.0' || urlParts.hostname === '[::]' || !urlParts.hostname;
93 // We only re-assign the hostname if it is empty,
94 // and if we are using HTTP/HTTPS protocols.
95 if (
96 isEmptyHostname &&
97 window.location.hostname &&
98 window.location.protocol.indexOf('http') === 0
99 ) {
100 urlParts.hostname = window.location.hostname;
101 }
102
103 // We only re-assign `protocol` when `protocol` is unavailable,
104 // or if `hostname` is available and is empty,
105 // since otherwise we risk creating an invalid URL.
106 // We also do this when no sockProtocol was passed to the config and 'https' is used,
107 // as it mandates the use of secure sockets.
108 if (
109 !urlParts.protocol ||
110 (urlParts.hostname &&
111 (isEmptyHostname || (!resourceQuery && window.location.protocol === 'https:')))
112 ) {
113 urlParts.protocol = window.location.protocol;
114 }
115
116 // We only re-assign port when it is not available
117 if (!urlParts.port) {
118 urlParts.port = window.location.port;
119 }
120
121 if (!urlParts.hostname || !urlParts.pathname) {
122 throw new Error(
123 [
124 '[React Refresh] Failed to get an URL for the socket connection.',
125 "This usually means that the current executed script doesn't have a `src` attribute set.",
126 'You should either specify the socket path parameters under the `devServer` key in your Webpack config, or use the `overlay` option.',
127 'https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/API.md#overlay',
128 ].join('\n')
129 );
130 }
131
132 return {
133 auth: urlParts.auth,
134 hostname: urlParts.hostname,
135 pathname: urlParts.pathname,
136 protocol: urlParts.protocol,
137 port: urlParts.port || undefined,
138 };
139}
140
141module.exports = getSocketUrlParts;
Note: See TracBrowser for help on using the repository browser.