Skip to content

Commit

Permalink
feat: add sockProtocol option to overlay (#242)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Mok <[email protected]>
  • Loading branch information
patrikholcak and pmmmwh authored Nov 19, 2020
1 parent e9ff50e commit 0d801aa
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 9 deletions.
12 changes: 12 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ interface ErrorOverlayOptions {
sockHost?: string;
sockPath?: string;
sockPort?: number;
sockProtocol?: 'http' | 'https' | 'ws' | 'wss';
useLegacyWDSSockets?: boolean;
}
```
Expand Down Expand Up @@ -185,6 +186,17 @@ Type: `string`
Set a custom path for the error overlay to listen to Webpack build messages.
Useful if you set `devServer.sockPath` to something other than `/sockjs-node`.

### `sockProtocol`

Default: parsed from current url

Type: `http`, `https`, `ws` or `wss`

**This is relevant for `webpack-dev-server` only.**

Force a protocol for the error overlay to listen for Webpack build messages.
Useful if you want to enforce https communication, or if you're working under a non-HTTP path.

#### `useLegacyWDSSockets`

Default: `undefined`
Expand Down
1 change: 1 addition & 0 deletions lib/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"sockHost": { "type": "string" },
"sockPath": { "type": "string" },
"sockPort": { "type": "number", "minimum": 0 },
"sockProtocol": { "enum": ["http", "https", "ws", "wss"] },
"useLegacyWDSSockets": { "type": "boolean" }
}
},
Expand Down
1 change: 1 addition & 0 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* @property {import('type-fest').LiteralUnion<'wds' | 'whm' | 'wps' | false, string>} [sockIntegration] Path to a JS file that sets up the Webpack socket integration.
* @property {string} [sockPath] The socket path to use (WDS only).
* @property {number} [sockPort] The socket port to use (WDS only).
* @property {'http' | 'https' | 'ws' | 'wss'} [sockProtocol] The socket protocol to use (WDS only).
* @property {boolean} [useLegacyWDSSockets] Uses a custom SocketJS implementation for older versions of webpack-dev-server.
*/

Expand Down
1 change: 1 addition & 0 deletions lib/utils/injectRefreshEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function injectRefreshEntry(originalEntry, options) {
options.overlay.sockHost && (resourceQuery.sockHost = options.overlay.sockHost);
options.overlay.sockPath && (resourceQuery.sockPath = options.overlay.sockPath);
options.overlay.sockPort && (resourceQuery.sockPort = options.overlay.sockPort);
options.overlay.sockProtocol && (resourceQuery.sockProtocol = options.overlay.sockProtocol);
}

// We don't need to URI encode the resourceQuery as it will be parsed by Webpack
Expand Down
1 change: 1 addition & 0 deletions lib/utils/normalizeOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const normalizeOptions = (options) => {
d(overlay, 'sockHost');
d(overlay, 'sockPath');
d(overlay, 'sockPort');
d(overlay, 'sockProtocol');
d(options, 'useLegacyWDSSockets');

return overlay;
Expand Down
5 changes: 5 additions & 0 deletions sockets/utils/getSocketUrlParts.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ function getSocketUrlParts(resourceQuery) {
pathname = parsedQuery.sockPath || pathname;
port = parsedQuery.sockPort || port;

// Make sure the protocol from resource query has a trailing colon
if (parsedQuery.sockProtocol) {
protocol = parsedQuery.sockProtocol + ':';
}

return {
auth: auth,
hostname: hostname,
Expand Down
6 changes: 4 additions & 2 deletions test/unit/getSocketUrlParts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,14 @@ describe('getSocketUrlParts', () => {
it('should use info from resource query when available', () => {
getCurrentScriptSource.mockImplementationOnce(() => 'http://localhost:8080');

expect(getSocketUrlParts('?sockHost=foo.com&sockPath=/socket&sockPort=9000')).toStrictEqual({
expect(
getSocketUrlParts('?sockProtocol=https&sockHost=foo.com&sockPath=/socket&sockPort=9000')
).toStrictEqual({
auth: undefined,
hostname: 'foo.com',
pathname: '/socket',
port: '9000',
protocol: 'http:',
protocol: 'https:',
});
});
});
3 changes: 2 additions & 1 deletion test/unit/injectRefreshEntry.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,12 @@ describe('injectRefreshEntry', () => {
sockHost: 'localhost',
sockPath: '/socket',
sockPort: '9000',
sockProtocol: 'https',
},
})
).toStrictEqual([
ReactRefreshEntry,
`${ErrorOverlayEntry}?sockHost=localhost&sockPath=/socket&sockPort=9000`,
`${ErrorOverlayEntry}?sockHost=localhost&sockPath=/socket&sockPort=9000&sockProtocol=https`,
'test.js',
]);
});
Expand Down
2 changes: 2 additions & 0 deletions test/unit/normalizeOptions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('normalizeOptions', () => {
sockIntegration: 'whm',
sockPath: '/socket',
sockPort: 9000,
sockProtocol: 'https:',
useLegacyWDSSockets: true,
},
})
Expand All @@ -42,6 +43,7 @@ describe('normalizeOptions', () => {
sockIntegration: 'whm',
sockPath: '/socket',
sockPort: 9000,
sockProtocol: 'https:',
useLegacyWDSSockets: true,
},
});
Expand Down
5 changes: 4 additions & 1 deletion test/unit/parseQuery.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ const parseQuery = require('../../sockets/utils/parseQuery');

describe('parseQuery', () => {
it('should handle valid query string', () => {
expect(parseQuery('?sockHost=localhost&sockPath=/__socket&sockPort=8080')).toStrictEqual({
expect(
parseQuery('?sockHost=localhost&sockPath=/__socket&sockPort=8080&sockProtocol=https')
).toStrictEqual({
sockHost: 'localhost',
sockPath: '/__socket',
sockPort: '8080',
sockProtocol: 'https',
});
});

Expand Down
38 changes: 33 additions & 5 deletions test/unit/validateOptions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ describe('validateOptions', () => {
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.
- options.overlay should be one of these:
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, useLegacyWDSSockets? }
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, sockProtocol?, useLegacyWDSSockets? }
Details:
* options.overlay should be a boolean.
* options.overlay should be an object:
object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, useLegacyWDSSockets? }"
object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, sockProtocol?, useLegacyWDSSockets? }"
`);
});

Expand Down Expand Up @@ -179,7 +179,7 @@ describe('validateOptions', () => {
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.
- options.overlay should be one of these:
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, useLegacyWDSSockets? }
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, sockProtocol?, useLegacyWDSSockets? }
Details:
* options.overlay.entry should be one of these:
false | string
Expand Down Expand Up @@ -224,7 +224,7 @@ describe('validateOptions', () => {
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.
- options.overlay should be one of these:
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, useLegacyWDSSockets? }
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, sockProtocol?, useLegacyWDSSockets? }
Details:
* options.overlay.module should be one of these:
false | string
Expand Down Expand Up @@ -293,7 +293,7 @@ describe('validateOptions', () => {
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.
- options.overlay should be one of these:
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, useLegacyWDSSockets? }
boolean | object { entry?, module?, sockIntegration?, sockHost?, sockPath?, sockPort?, sockProtocol?, useLegacyWDSSockets? }
Details:
* options.overlay.sockIntegration should be one of these:
false | \\"wds\\" | \\"whm\\" | \\"wps\\" | string
Expand Down Expand Up @@ -381,6 +381,34 @@ describe('validateOptions', () => {
`);
});

it('should accept "overlay.sockProtocol" when it is "http"', () => {
expect(() => {
new ReactRefreshPlugin({
overlay: { sockProtocol: 'http' },
});
}).not.toThrow();
});

it('should accept "overlay.sockProtocol" when it is "https"', () => {
expect(() => {
new ReactRefreshPlugin({
overlay: { sockProtocol: 'https' },
});
}).not.toThrow();
});

it('should reject "overlay.sockProtocol" when it is not "http", "https", "ws" nor "wss"', () => {
expect(() => {
new ReactRefreshPlugin({
overlay: { sockProtocol: true },
});
}).toThrowErrorMatchingInlineSnapshot(`
"Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.
- options.overlay.sockProtocol should be one of these:
\\"http\\" | \\"https\\" | \\"ws\\" | \\"wss\\""
`);
});

it('should accept "overlay.useLegacyWDSSockets" when it is true', () => {
expect(() => {
new ReactRefreshPlugin({
Expand Down
8 changes: 8 additions & 0 deletions types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export type ErrorOverlayOptions = {
* The socket port to use (WDS only).
*/
sockPort?: number;
/**
* The socket protocol to use (WDS only).
*/
sockProtocol?: 'http' | 'https' | 'ws' | 'wss';
/**
* Uses a custom SocketJS implementation for older versions of webpack-dev-server.
*/
Expand All @@ -41,6 +45,10 @@ export type NormalizedErrorOverlayOptions = {
* The socket port to use (WDS only).
*/
sockPort?: number | undefined;
/**
* The socket protocol to use (WDS only).
*/
sockProtocol?: 'http' | 'https' | 'ws' | 'wss';
/**
* Uses a custom SocketJS implementation for older versions of webpack-dev-server.
*/
Expand Down

0 comments on commit 0d801aa

Please sign in to comment.