@storybook/react-native 10.3.0-next.6 → 10.3.0

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Options for configuring WebSockets used for syncing storybook instances or sending events to storybook.
3
+ */
4
+ interface WebsocketsOptions {
5
+ /**
6
+ * The port WebSocket server will listen on. Defaults to 7007.
7
+ */
8
+ port?: number;
9
+ /**
10
+ * The host WebSocket server will bind to. Defaults to 'localhost'.
11
+ */
12
+ host?: string;
13
+ /**
14
+ * Whether to use WSS/HTTPS for the channel server.
15
+ */
16
+ secured?: boolean;
17
+ /**
18
+ * TLS private key used when `secured` is true.
19
+ */
20
+ key?: string | Buffer;
21
+ /**
22
+ * TLS certificate used when `secured` is true.
23
+ */
24
+ cert?: string | Buffer;
25
+ /**
26
+ * Optional certificate authority chain used when `secured` is true.
27
+ */
28
+ ca?: string | Buffer | Array<string | Buffer>;
29
+ /**
30
+ * Optional TLS passphrase used when `secured` is true.
31
+ */
32
+ passphrase?: string;
33
+ }
34
+
35
+ export type { WebsocketsOptions as W };
package/dist/index.d.ts CHANGED
@@ -78,6 +78,7 @@ declare class View {
78
78
  }>;
79
79
  _getHost: (params?: Partial<Params>) => any;
80
80
  __getPort: (params?: Partial<Params>) => any;
81
+ _isSecureConnection: (params?: Partial<Params>) => any;
81
82
  _getServerChannel: (params?: Partial<Params>) => Channel;
82
83
  createPreparedStoryMapping: () => Promise<void>;
83
84
  getStorybookUI: (params?: Partial<Params>) => () => react_jsx_runtime.JSX.Element;
package/dist/index.js CHANGED
@@ -1389,11 +1389,17 @@ var View3 = class {
1389
1389
  }
1390
1390
  return 7007;
1391
1391
  };
1392
+ _isSecureConnection = (params = {}) => {
1393
+ if (typeof params.secured === "boolean") {
1394
+ return params.secured;
1395
+ }
1396
+ return globalThis.STORYBOOK_WEBSOCKET?.secured ?? false;
1397
+ };
1392
1398
  _getServerChannel = (params = {}) => {
1393
1399
  const host = this._getHost(params);
1394
1400
  const port = `:${this.__getPort(params)}`;
1395
1401
  const query = params.query || "";
1396
- const websocketType = params.secured ? "wss" : "ws";
1402
+ const websocketType = this._isSecureConnection(params) ? "wss" : "ws";
1397
1403
  const url = `${websocketType}://${host}${port}/${query}`;
1398
1404
  const channel = new import_channels.Channel({
1399
1405
  async: true,
@@ -1,18 +1,6 @@
1
1
  import { MetroConfig } from 'metro-config';
2
+ import { W as WebsocketsOptions } from '../index-6iAzVvXp.js';
2
3
 
3
- /**
4
- * Options for configuring WebSockets used for syncing storybook instances or sending events to storybook.
5
- */
6
- interface WebsocketsOptions {
7
- /**
8
- * The port WebSocket server will listen on. Defaults to 7007.
9
- */
10
- port?: number;
11
- /**
12
- * The host WebSocket server will bind to. Defaults to 'localhost'.
13
- */
14
- host?: string;
15
- }
16
4
  /**
17
5
  * Options for configuring Storybook with React Native.
18
6
  */
@@ -64,6 +52,9 @@ interface WithStorybookOptions {
64
52
  * When provided, creates a WebSocket server for real-time communication.
65
53
  * @param options.websockets.port - The port WebSocket server will listen on. Defaults to 7007.
66
54
  * @param options.websockets.host - The host WebSocket server will bind to. Defaults to 'localhost'.
55
+ * @param options.websockets.secured - Whether to use WSS/HTTPS for the channel server.
56
+ * @param options.websockets.key - TLS private key used when `secured` is true.
57
+ * @param options.websockets.cert - TLS certificate used when `secured` is true.
67
58
  * @param options.useJs - Whether to use JavaScript files for Storybook configuration instead of TypeScript.
68
59
  * When true, generates storybook.requires.js instead of storybook.requires.ts.
69
60
  * Defaults to false.
@@ -201,7 +201,8 @@ var require_generate = __commonJS({
201
201
  useJs = false,
202
202
  docTools = true,
203
203
  host = void 0,
204
- port = 7007
204
+ port = void 0,
205
+ secured = false
205
206
  }) {
206
207
  const channelHost = host === "auto" ? getLocalIPAddress() : host;
207
208
  const storybookRequiresLocation = path3.resolve(
@@ -284,11 +285,22 @@ var require_generate = __commonJS({
284
285
  const annotations = `[
285
286
  ${enhancers.join(",\n ")}
286
287
  ]`;
288
+ const hasWebsocketConfig = host !== void 0 || port !== void 0 || secured;
289
+ const websocketAssignmentLines = [];
290
+ if (channelHost) {
291
+ websocketAssignmentLines.push(`host: '${channelHost}',`);
292
+ }
293
+ if (hasWebsocketConfig) {
294
+ websocketAssignmentLines.push(`port: ${port ?? 7007},`);
295
+ websocketAssignmentLines.push(`secured: ${Boolean(secured)},`);
296
+ }
287
297
  const globalTypes = `
288
298
  declare global {
289
299
  var view: View;
290
300
  var STORIES: typeof normalizedStories;
291
- var STORYBOOK_WEBSOCKET: { host: string; port: number } | undefined;
301
+ var STORYBOOK_WEBSOCKET:
302
+ | { host?: string; port?: number; secured?: boolean }
303
+ | undefined;
292
304
  var FEATURES: Features;
293
305
  }
294
306
  `;
@@ -306,7 +318,9 @@ ${useJs ? "" : globalTypes}
306
318
  const annotations = ${annotations};
307
319
 
308
320
  globalThis.STORIES = normalizedStories;
309
- ${channelHost ? `globalThis.STORYBOOK_WEBSOCKET = { host: '${channelHost}', port: ${port ?? 7007} };` : ""}
321
+ ${hasWebsocketConfig ? `globalThis.STORYBOOK_WEBSOCKET = {
322
+ ${websocketAssignmentLines.join("\n ")}
323
+ };` : ""}
310
324
 
311
325
  module?.hot?.accept?.();
312
326
  ${featuresAssignment ? `
@@ -574,6 +588,7 @@ var import_telemetry = require("storybook/internal/telemetry");
574
588
  // src/metro/channelServer.ts
575
589
  var import_ws2 = require("ws");
576
590
  var import_node_http = require("http");
591
+ var import_node_https = require("https");
577
592
  init_buildIndex();
578
593
 
579
594
  // src/metro/mcpServer.ts
@@ -951,14 +966,20 @@ function createChannelServer({
951
966
  host = void 0,
952
967
  configPath,
953
968
  experimental_mcp = false,
954
- websockets = true
969
+ websockets = true,
970
+ secured = false,
971
+ ssl
955
972
  }) {
956
- const httpServer = (0, import_node_http.createServer)();
973
+ if (secured && (!ssl?.key || !ssl?.cert)) {
974
+ throw new Error("[Storybook] Secure channel server requires both `ssl.key` and `ssl.cert`.");
975
+ }
976
+ const httpServer = secured ? (0, import_node_https.createServer)(ssl) : (0, import_node_http.createServer)();
957
977
  const wss = websockets ? new import_ws2.WebSocketServer({ server: httpServer }) : null;
958
978
  const mcpServer = experimental_mcp ? createMcpHandler(configPath, wss ?? void 0) : null;
959
979
  const selectStorySyncEndpoint = wss ? createSelectStorySyncEndpoint(wss) : null;
960
980
  httpServer.on("request", async (req, res) => {
961
- const requestUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
981
+ const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
982
+ const requestUrl = new URL(req.url ?? "/", `${protocol}://${req.headers.host ?? "localhost"}`);
962
983
  if (req.method === "OPTIONS") {
963
984
  res.writeHead(204);
964
985
  res.end();
@@ -1059,7 +1080,7 @@ function createChannelServer({
1059
1080
  }
1060
1081
  });
1061
1082
  httpServer.listen(port, host, () => {
1062
- const protocol = wss ? "WebSocket" : "HTTP";
1083
+ const protocol = wss ? secured ? "WSS" : "WebSocket" : secured ? "HTTPS" : "HTTP";
1063
1084
  console.log(`${protocol} server listening on ${host ?? "localhost"}:${port}`);
1064
1085
  });
1065
1086
  mcpServer?.preInit();
@@ -1125,12 +1146,20 @@ function withStorybook(config, options = {
1125
1146
  if (websockets || experimental_mcp) {
1126
1147
  const port = websockets === "auto" ? 7007 : websockets?.port ?? 7007;
1127
1148
  const host = websockets === "auto" ? "auto" : websockets?.host;
1149
+ const secured = Boolean(websockets && websockets !== "auto" && websockets.secured);
1128
1150
  createChannelServer({
1129
1151
  port,
1130
1152
  host: host === "auto" ? void 0 : host,
1131
1153
  configPath,
1132
1154
  experimental_mcp,
1133
- websockets: Boolean(websockets)
1155
+ websockets: Boolean(websockets),
1156
+ secured,
1157
+ ssl: websockets && websockets !== "auto" ? {
1158
+ key: websockets.key,
1159
+ cert: websockets.cert,
1160
+ ca: websockets.ca,
1161
+ passphrase: websockets.passphrase
1162
+ } : void 0
1134
1163
  });
1135
1164
  if (websockets) {
1136
1165
  (0, import_generate.generate)({
@@ -1138,7 +1167,8 @@ function withStorybook(config, options = {
1138
1167
  useJs,
1139
1168
  docTools,
1140
1169
  host,
1141
- port
1170
+ port,
1171
+ secured
1142
1172
  });
1143
1173
  } else {
1144
1174
  (0, import_generate.generate)({
package/dist/node.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  import { WebSocketServer } from 'ws';
2
2
  import { StoryIndex } from 'storybook/internal/types';
3
3
 
4
+ interface ChannelServerSecureOptions {
5
+ ca?: string | Buffer | Array<string | Buffer>;
6
+ cert?: string | Buffer | Array<string | Buffer>;
7
+ key?: string | Buffer | Array<string | Buffer>;
8
+ passphrase?: string;
9
+ }
4
10
  /**
5
11
  * Options for creating a channel server.
6
12
  */
@@ -27,6 +33,15 @@ interface ChannelServerOptions {
27
33
  * When false, starts only the HTTP server endpoints.
28
34
  */
29
35
  websockets?: boolean;
36
+ /**
37
+ * Whether to use HTTPS/WSS for the channel server.
38
+ * When true, valid TLS credentials must be provided via `ssl`.
39
+ */
40
+ secured?: boolean;
41
+ /**
42
+ * TLS credentials used when `secured` is true.
43
+ */
44
+ ssl?: ChannelServerSecureOptions;
30
45
  }
31
46
  /**
32
47
  * Creates a channel server for syncing storybook instances and sending events.
@@ -43,9 +58,11 @@ interface ChannelServerOptions {
43
58
  * @param options.configPath - The path to the Storybook config folder.
44
59
  * @param options.experimental_mcp - Whether to enable MCP server support.
45
60
  * @param options.websockets - Whether to enable WebSocket server support.
61
+ * @param options.secured - Whether to use HTTPS/WSS for the channel server.
62
+ * @param options.ssl - TLS credentials used when `secured` is true.
46
63
  * @returns The created WebSocketServer instance, or null when websockets are disabled.
47
64
  */
48
- declare function createChannelServer({ port, host, configPath, experimental_mcp, websockets, }: ChannelServerOptions): WebSocketServer | null;
65
+ declare function createChannelServer({ port, host, configPath, experimental_mcp, websockets, secured, ssl, }: ChannelServerOptions): WebSocketServer | null;
49
66
 
50
67
  declare function buildIndex({ configPath }: {
51
68
  configPath: string;
package/dist/node.js CHANGED
@@ -353,6 +353,7 @@ module.exports = __toCommonJS(node_exports);
353
353
  // src/metro/channelServer.ts
354
354
  var import_ws2 = require("ws");
355
355
  var import_node_http = require("http");
356
+ var import_node_https = require("https");
356
357
  init_buildIndex();
357
358
 
358
359
  // src/metro/mcpServer.ts
@@ -730,14 +731,20 @@ function createChannelServer({
730
731
  host = void 0,
731
732
  configPath,
732
733
  experimental_mcp = false,
733
- websockets = true
734
+ websockets = true,
735
+ secured = false,
736
+ ssl
734
737
  }) {
735
- const httpServer = (0, import_node_http.createServer)();
738
+ if (secured && (!ssl?.key || !ssl?.cert)) {
739
+ throw new Error("[Storybook] Secure channel server requires both `ssl.key` and `ssl.cert`.");
740
+ }
741
+ const httpServer = secured ? (0, import_node_https.createServer)(ssl) : (0, import_node_http.createServer)();
736
742
  const wss = websockets ? new import_ws2.WebSocketServer({ server: httpServer }) : null;
737
743
  const mcpServer = experimental_mcp ? createMcpHandler(configPath, wss ?? void 0) : null;
738
744
  const selectStorySyncEndpoint = wss ? createSelectStorySyncEndpoint(wss) : null;
739
745
  httpServer.on("request", async (req, res) => {
740
- const requestUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
746
+ const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
747
+ const requestUrl = new URL(req.url ?? "/", `${protocol}://${req.headers.host ?? "localhost"}`);
741
748
  if (req.method === "OPTIONS") {
742
749
  res.writeHead(204);
743
750
  res.end();
@@ -838,7 +845,7 @@ function createChannelServer({
838
845
  }
839
846
  });
840
847
  httpServer.listen(port, host, () => {
841
- const protocol = wss ? "WebSocket" : "HTTP";
848
+ const protocol = wss ? secured ? "WSS" : "WebSocket" : secured ? "HTTPS" : "HTTP";
842
849
  console.log(`${protocol} server listening on ${host ?? "localhost"}:${port}`);
843
850
  });
844
851
  mcpServer?.preInit();
@@ -1,3 +1,5 @@
1
+ import { W as WebsocketsOptions } from '../index-6iAzVvXp.js';
2
+
1
3
  /**
2
4
  * Minimal compiler types for webpack/rspack compatibility.
3
5
  * We define these inline to avoid requiring @rspack/core or webpack as dependencies.
@@ -21,19 +23,6 @@ interface Compiler {
21
23
  };
22
24
  };
23
25
  }
24
- /**
25
- * Options for configuring WebSockets used for syncing storybook instances or sending events to storybook.
26
- */
27
- interface WebsocketsOptions {
28
- /**
29
- * The port WebSocket server will listen on. Defaults to 7007.
30
- */
31
- port?: number;
32
- /**
33
- * The host WebSocket server will bind to. Defaults to 'localhost'.
34
- */
35
- host?: string;
36
- }
37
26
  /**
38
27
  * Options for configuring the Storybook Repack plugin.
39
28
  */
@@ -201,7 +201,8 @@ var require_generate = __commonJS({
201
201
  useJs = false,
202
202
  docTools = true,
203
203
  host = void 0,
204
- port = 7007
204
+ port = void 0,
205
+ secured = false
205
206
  }) {
206
207
  const channelHost = host === "auto" ? getLocalIPAddress() : host;
207
208
  const storybookRequiresLocation = path3.resolve(
@@ -284,11 +285,22 @@ var require_generate = __commonJS({
284
285
  const annotations = `[
285
286
  ${enhancers.join(",\n ")}
286
287
  ]`;
288
+ const hasWebsocketConfig = host !== void 0 || port !== void 0 || secured;
289
+ const websocketAssignmentLines = [];
290
+ if (channelHost) {
291
+ websocketAssignmentLines.push(`host: '${channelHost}',`);
292
+ }
293
+ if (hasWebsocketConfig) {
294
+ websocketAssignmentLines.push(`port: ${port ?? 7007},`);
295
+ websocketAssignmentLines.push(`secured: ${Boolean(secured)},`);
296
+ }
287
297
  const globalTypes = `
288
298
  declare global {
289
299
  var view: View;
290
300
  var STORIES: typeof normalizedStories;
291
- var STORYBOOK_WEBSOCKET: { host: string; port: number } | undefined;
301
+ var STORYBOOK_WEBSOCKET:
302
+ | { host?: string; port?: number; secured?: boolean }
303
+ | undefined;
292
304
  var FEATURES: Features;
293
305
  }
294
306
  `;
@@ -306,7 +318,9 @@ ${useJs ? "" : globalTypes}
306
318
  const annotations = ${annotations};
307
319
 
308
320
  globalThis.STORIES = normalizedStories;
309
- ${channelHost ? `globalThis.STORYBOOK_WEBSOCKET = { host: '${channelHost}', port: ${port ?? 7007} };` : ""}
321
+ ${hasWebsocketConfig ? `globalThis.STORYBOOK_WEBSOCKET = {
322
+ ${websocketAssignmentLines.join("\n ")}
323
+ };` : ""}
310
324
 
311
325
  module?.hot?.accept?.();
312
326
  ${featuresAssignment ? `
@@ -572,6 +586,7 @@ var import_generate = __toESM(require_generate());
572
586
  // src/metro/channelServer.ts
573
587
  var import_ws2 = require("ws");
574
588
  var import_node_http = require("http");
589
+ var import_node_https = require("https");
575
590
  init_buildIndex();
576
591
 
577
592
  // src/metro/mcpServer.ts
@@ -949,14 +964,20 @@ function createChannelServer({
949
964
  host = void 0,
950
965
  configPath,
951
966
  experimental_mcp = false,
952
- websockets = true
967
+ websockets = true,
968
+ secured = false,
969
+ ssl
953
970
  }) {
954
- const httpServer = (0, import_node_http.createServer)();
971
+ if (secured && (!ssl?.key || !ssl?.cert)) {
972
+ throw new Error("[Storybook] Secure channel server requires both `ssl.key` and `ssl.cert`.");
973
+ }
974
+ const httpServer = secured ? (0, import_node_https.createServer)(ssl) : (0, import_node_http.createServer)();
955
975
  const wss = websockets ? new import_ws2.WebSocketServer({ server: httpServer }) : null;
956
976
  const mcpServer = experimental_mcp ? createMcpHandler(configPath, wss ?? void 0) : null;
957
977
  const selectStorySyncEndpoint = wss ? createSelectStorySyncEndpoint(wss) : null;
958
978
  httpServer.on("request", async (req, res) => {
959
- const requestUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
979
+ const protocol = "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
980
+ const requestUrl = new URL(req.url ?? "/", `${protocol}://${req.headers.host ?? "localhost"}`);
960
981
  if (req.method === "OPTIONS") {
961
982
  res.writeHead(204);
962
983
  res.end();
@@ -1057,7 +1078,7 @@ function createChannelServer({
1057
1078
  }
1058
1079
  });
1059
1080
  httpServer.listen(port, host, () => {
1060
- const protocol = wss ? "WebSocket" : "HTTP";
1081
+ const protocol = wss ? secured ? "WSS" : "WebSocket" : secured ? "HTTPS" : "HTTP";
1061
1082
  console.log(`${protocol} server listening on ${host ?? "localhost"}:${port}`);
1062
1083
  });
1063
1084
  mcpServer?.preInit();
@@ -1109,6 +1130,7 @@ var StorybookPlugin = class {
1109
1130
  }) {
1110
1131
  const port = websockets === "auto" ? 7007 : websockets?.port ?? 7007;
1111
1132
  const host = websockets === "auto" ? "auto" : websockets?.host;
1133
+ const secured = Boolean(websockets && websockets !== "auto" && websockets.secured);
1112
1134
  if ((websockets || experimental_mcp) && !this.serverStarted) {
1113
1135
  this.serverStarted = true;
1114
1136
  createChannelServer({
@@ -1116,7 +1138,14 @@ var StorybookPlugin = class {
1116
1138
  host: host === "auto" ? void 0 : host,
1117
1139
  configPath,
1118
1140
  experimental_mcp,
1119
- websockets: Boolean(websockets)
1141
+ websockets: Boolean(websockets),
1142
+ secured,
1143
+ ssl: websockets && websockets !== "auto" ? {
1144
+ key: websockets.key,
1145
+ cert: websockets.cert,
1146
+ ca: websockets.ca,
1147
+ passphrase: websockets.passphrase
1148
+ } : void 0
1120
1149
  });
1121
1150
  }
1122
1151
  compiler.hooks.beforeCompile.tapPromise("StorybookPlugin", async () => {
@@ -1126,7 +1155,7 @@ var StorybookPlugin = class {
1126
1155
  configPath,
1127
1156
  useJs,
1128
1157
  docTools,
1129
- ...websockets ? { host, port } : {}
1158
+ ...websockets ? { host, port, secured } : {}
1130
1159
  });
1131
1160
  console.log("[StorybookPlugin] Generated storybook.requires");
1132
1161
  });
@@ -1141,7 +1170,10 @@ var StorybookPlugin = class {
1141
1170
  * and replace the config folder index with a stub component.
1142
1171
  */
1143
1172
  applyDisabled(compiler, configPath) {
1144
- const stubPath = require.resolve("@storybook/react-native/stub");
1173
+ const stubPath = path2.resolve(
1174
+ __dirname,
1175
+ __dirname.includes(`${path2.sep}src${path2.sep}`) ? "../stub.tsx" : "../stub.js"
1176
+ );
1145
1177
  const normalizedConfigPath = path2.resolve(configPath);
1146
1178
  new compiler.webpack.NormalModuleReplacementPlugin(/./, (resource) => {
1147
1179
  const request = resource.request;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react-native",
3
- "version": "10.3.0-next.6",
3
+ "version": "10.3.0",
4
4
  "description": "A better way to develop React Native Components for your app",
5
5
  "keywords": [
6
6
  "react",
@@ -45,9 +45,9 @@
45
45
  "dependencies": {
46
46
  "@storybook/mcp": "^0.4.1",
47
47
  "@storybook/react": "10.3.0-alpha.14",
48
- "@storybook/react-native-theming": "^10.3.0-next.6",
49
- "@storybook/react-native-ui": "^10.3.0-next.6",
50
- "@storybook/react-native-ui-common": "^10.3.0-next.6",
48
+ "@storybook/react-native-theming": "^10.3.0",
49
+ "@storybook/react-native-ui": "^10.3.0",
50
+ "@storybook/react-native-ui-common": "^10.3.0",
51
51
  "@tmcp/adapter-valibot": "^0.1.4",
52
52
  "@tmcp/transport-http": "^0.8.0",
53
53
  "commander": "^14.0.2",
package/readme.md CHANGED
@@ -461,7 +461,7 @@ You can enable MCP with or without websockets:
461
461
 
462
462
  ### websockets
463
463
 
464
- Type: `'auto' | { host: string?, port: number? }`, default: `undefined`
464
+ Type: `'auto' | { host?: string, port?: number, secured?: boolean, key?: string | Buffer, cert?: string | Buffer, ca?: string | Buffer | Array<string | Buffer>, passphrase?: string }`, default: `undefined`
465
465
 
466
466
  If specified, create a WebSocket server on startup. This allows you to sync up multiple devices to show the same story and [arg](https://storybook.js.org/docs/writing-stories/args) values connected to the story in the UI.
467
467
 
@@ -479,6 +479,18 @@ Type: `number`, default: `7007`
479
479
 
480
480
  The port on which to run the WebSocket, if specified.
481
481
 
482
+ ### websockets.secured
483
+
484
+ Type: `boolean`, default: `false`
485
+
486
+ When `true`, the channel server starts on `https` and upgrades WebSocket clients over `wss`.
487
+
488
+ ### websockets.key / websockets.cert
489
+
490
+ Type: `string | Buffer`, default: `undefined`
491
+
492
+ TLS private key and certificate used when `secured` is `true`.
493
+
482
494
  ## getStorybookUI options
483
495
 
484
496
  You can pass these parameters to getStorybookUI call in your storybook entry point:
@@ -55,7 +55,8 @@ async function generate({
55
55
  useJs = false,
56
56
  docTools = true,
57
57
  host = undefined,
58
- port = 7007,
58
+ port = undefined,
59
+ secured = false,
59
60
  }) {
60
61
  // here we want to get the ip address and pass it to rn storybook so that devices can connect over lan easily
61
62
  const channelHost = host === 'auto' ? getLocalIPAddress() : host;
@@ -165,11 +166,25 @@ async function generate({
165
166
  ${enhancers.join(',\n ')}
166
167
  ]`;
167
168
 
169
+ const hasWebsocketConfig = host !== undefined || port !== undefined || secured;
170
+ const websocketAssignmentLines = [];
171
+
172
+ if (channelHost) {
173
+ websocketAssignmentLines.push(`host: '${channelHost}',`);
174
+ }
175
+
176
+ if (hasWebsocketConfig) {
177
+ websocketAssignmentLines.push(`port: ${port ?? 7007},`);
178
+ websocketAssignmentLines.push(`secured: ${Boolean(secured)},`);
179
+ }
180
+
168
181
  const globalTypes = `
169
182
  declare global {
170
183
  var view: View;
171
184
  var STORIES: typeof normalizedStories;
172
- var STORYBOOK_WEBSOCKET: { host: string; port: number } | undefined;
185
+ var STORYBOOK_WEBSOCKET:
186
+ | { host?: string; port?: number; secured?: boolean }
187
+ | undefined;
173
188
  var FEATURES: Features;
174
189
  }
175
190
  `;
@@ -188,7 +203,13 @@ ${useJs ? '' : globalTypes}
188
203
  const annotations = ${annotations};
189
204
 
190
205
  globalThis.STORIES = normalizedStories;
191
- ${channelHost ? `globalThis.STORYBOOK_WEBSOCKET = { host: '${channelHost}', port: ${port ?? 7007} };` : ''}
206
+ ${
207
+ hasWebsocketConfig
208
+ ? `globalThis.STORYBOOK_WEBSOCKET = {
209
+ ${websocketAssignmentLines.join('\n ')}
210
+ };`
211
+ : ''
212
+ }
192
213
 
193
214
  module?.hot?.accept?.();
194
215
  ${featuresAssignment ? `\n${featuresAssignment}\n` : ''}