@react-native/dev-middleware 0.77.0-nightly-20241120-a865975ce → 0.77.0-nightly-20241122-e4d8c9678

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.
@@ -21,6 +21,7 @@ export type DeviceOptions = Readonly<{
21
21
  projectRoot: string;
22
22
  eventReporter: null | undefined | EventReporter;
23
23
  createMessageMiddleware: null | undefined | CreateCustomMessageHandlerFn;
24
+ deviceRelativeBaseUrl: URL;
24
25
  serverRelativeBaseUrl: URL;
25
26
  }>;
26
27
  /**
@@ -36,7 +37,10 @@ declare class Device {
36
37
  handleDebuggerConnection(
37
38
  socket: WS,
38
39
  pageId: string,
39
- metadata: Readonly<{ userAgent: string | null }>
40
+ $$PARAM_2$$: Readonly<{
41
+ debuggerRelativeBaseUrl: URL;
42
+ userAgent: string | null;
43
+ }>
40
44
  ): void;
41
45
  dangerouslyGetSocket(): WS;
42
46
  }
@@ -39,7 +39,11 @@ function _interopRequireDefault(e) {
39
39
  }
40
40
  const debug = require("debug")("Metro:InspectorProxy");
41
41
  const PAGES_POLLING_INTERVAL = 1000;
42
- const REWRITE_HOSTS_TO_LOCALHOST = ["127.0.0.1", "10.0.2.2", "10.0.3.2"];
42
+ const REWRITE_HOSTS_TO_LOCALHOST = new Set([
43
+ "127.0.0.1",
44
+ "10.0.2.2",
45
+ "10.0.3.2",
46
+ ]);
43
47
  const FILE_PREFIX = "file://";
44
48
  const REACT_NATIVE_RELOADABLE_PAGE_ID = "-1";
45
49
  class Device {
@@ -59,6 +63,7 @@ class Device {
59
63
  #pagesPollingIntervalId;
60
64
  #createCustomMessageHandler;
61
65
  #connectedPageIds = new Set();
66
+ #deviceRelativeBaseUrl;
62
67
  #serverRelativeBaseUrl;
63
68
  constructor(deviceOptions) {
64
69
  this.#dangerouslyConstruct(deviceOptions);
@@ -72,6 +77,7 @@ class Device {
72
77
  eventReporter,
73
78
  createMessageMiddleware,
74
79
  serverRelativeBaseUrl,
80
+ deviceRelativeBaseUrl,
75
81
  }) {
76
82
  this.#id = id;
77
83
  this.#name = name;
@@ -79,6 +85,7 @@ class Device {
79
85
  this.#deviceSocket = socket;
80
86
  this.#projectRoot = projectRoot;
81
87
  this.#serverRelativeBaseUrl = serverRelativeBaseUrl;
88
+ this.#deviceRelativeBaseUrl = deviceRelativeBaseUrl;
82
89
  this.#deviceEventReporter = eventReporter
83
90
  ? new _DeviceEventReporter.default(eventReporter, {
84
91
  deviceId: id,
@@ -160,6 +167,7 @@ class Device {
160
167
  oldDebugger.socket.removeAllListeners();
161
168
  this.#deviceSocket.close();
162
169
  this.handleDebuggerConnection(oldDebugger.socket, oldDebugger.pageId, {
170
+ debuggerRelativeBaseUrl: oldDebugger.debuggerRelativeBaseUrl,
163
171
  userAgent: oldDebugger.userAgent,
164
172
  });
165
173
  }
@@ -178,16 +186,19 @@ class Device {
178
186
  return [...this.#pages.values()];
179
187
  }
180
188
  }
181
- handleDebuggerConnection(socket, pageId, metadata) {
189
+ handleDebuggerConnection(
190
+ socket,
191
+ pageId,
192
+ { debuggerRelativeBaseUrl, userAgent }
193
+ ) {
182
194
  const page =
183
195
  pageId === REACT_NATIVE_RELOADABLE_PAGE_ID
184
196
  ? this.#createSyntheticPage()
185
197
  : this.#pages.get(pageId);
186
198
  if (!page) {
187
199
  debug(
188
- `Got new debugger connection for page ${pageId} of ${
189
- this.#name
190
- }, but no such page exists`
200
+ `Got new debugger connection via ${debuggerRelativeBaseUrl.href} for ` +
201
+ `page ${pageId} of ${this.#name}, but no such page exists`
191
202
  );
192
203
  socket.close();
193
204
  return;
@@ -196,17 +207,21 @@ class Device {
196
207
  this.#terminateDebuggerConnection();
197
208
  this.#deviceEventReporter?.logConnection("debugger", {
198
209
  pageId,
199
- frontendUserAgent: metadata.userAgent,
210
+ frontendUserAgent: userAgent,
200
211
  });
201
212
  const debuggerInfo = {
202
213
  socket,
203
214
  prependedFilePrefix: false,
204
215
  pageId,
205
- userAgent: metadata.userAgent,
216
+ userAgent: userAgent,
206
217
  customHandler: null,
218
+ debuggerRelativeBaseUrl,
207
219
  };
208
220
  this.#debuggerConnection = debuggerInfo;
209
- debug(`Got new debugger connection for page ${pageId} of ${this.#name}`);
221
+ debug(
222
+ `Got new debugger connection via ${debuggerRelativeBaseUrl.href} for ` +
223
+ `page ${pageId} of ${this.#name}`
224
+ );
210
225
  if (this.#debuggerConnection && this.#createCustomMessageHandler) {
211
226
  this.#debuggerConnection.customHandler = this.#createCustomMessageHandler(
212
227
  {
@@ -255,7 +270,7 @@ class Device {
255
270
  const debuggerRequest = JSON.parse(message);
256
271
  this.#deviceEventReporter?.logRequest(debuggerRequest, "debugger", {
257
272
  pageId: this.#debuggerConnection?.pageId ?? null,
258
- frontendUserAgent: metadata.userAgent,
273
+ frontendUserAgent: userAgent,
259
274
  prefersFuseboxFrontend: this.#isPageFuseboxFrontend(
260
275
  this.#debuggerConnection?.pageId
261
276
  ),
@@ -497,16 +512,20 @@ class Device {
497
512
  const sourceMapURL = this.#tryParseHTTPURL(params.sourceMapURL);
498
513
  if (sourceMapURL) {
499
514
  const serverRelativeUrl = new URL(sourceMapURL.href);
500
- for (const hostToRewrite of REWRITE_HOSTS_TO_LOCALHOST) {
501
- if (params.sourceMapURL.includes(hostToRewrite)) {
502
- payload.params.sourceMapURL = params.sourceMapURL.replace(
503
- hostToRewrite,
504
- "localhost"
505
- );
506
- debuggerInfo.originalSourceURLAddress = hostToRewrite;
507
- serverRelativeUrl.host = this.#serverRelativeBaseUrl.host;
508
- serverRelativeUrl.protocol = this.#serverRelativeBaseUrl.protocol;
509
- }
515
+ if (
516
+ sourceMapURL.origin === this.#deviceRelativeBaseUrl.origin &&
517
+ REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname)
518
+ ) {
519
+ const debuggerRelativeURL = new URL(sourceMapURL.href);
520
+ debuggerRelativeURL.host =
521
+ debuggerInfo.debuggerRelativeBaseUrl.host;
522
+ debuggerRelativeURL.protocol =
523
+ debuggerInfo.debuggerRelativeBaseUrl.protocol;
524
+ serverRelativeUrl.host = this.#serverRelativeBaseUrl.host;
525
+ serverRelativeUrl.protocol = this.#serverRelativeBaseUrl.protocol;
526
+ debuggerInfo.originalSourceURLOrigin =
527
+ this.#deviceRelativeBaseUrl.origin;
528
+ payload.params.sourceMapURL = debuggerRelativeURL.href;
510
529
  }
511
530
  try {
512
531
  const sourceMap = await this.#fetchText(serverRelativeUrl);
@@ -521,20 +540,21 @@ class Device {
521
540
  }
522
541
  }
523
542
  if ("url" in params) {
524
- const originalParamsUrl = params.url;
525
- let serverRelativeUrl = originalParamsUrl;
526
- const parsedUrl = this.#tryParseHTTPURL(originalParamsUrl);
527
- if (parsedUrl) {
528
- for (const hostToRewrite of REWRITE_HOSTS_TO_LOCALHOST) {
529
- if (parsedUrl.hostname === hostToRewrite) {
530
- parsedUrl.hostname = "localhost";
531
- payload.params.url = parsedUrl.href;
532
- debuggerInfo.originalSourceURLAddress = hostToRewrite;
533
- parsedUrl.host = this.#serverRelativeBaseUrl.host;
534
- parsedUrl.protocol = this.#serverRelativeBaseUrl.protocol;
535
- serverRelativeUrl = parsedUrl.href;
536
- }
537
- }
543
+ let serverRelativeUrl = params.url;
544
+ const parsedUrl = this.#tryParseHTTPURL(params.url);
545
+ if (
546
+ parsedUrl &&
547
+ parsedUrl.origin === this.#deviceRelativeBaseUrl.origin &&
548
+ REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname)
549
+ ) {
550
+ parsedUrl.host = debuggerInfo.debuggerRelativeBaseUrl.host;
551
+ parsedUrl.protocol = debuggerInfo.debuggerRelativeBaseUrl.protocol;
552
+ payload.params.url = parsedUrl.href;
553
+ debuggerInfo.originalSourceURLOrigin =
554
+ this.#deviceRelativeBaseUrl.origin;
555
+ parsedUrl.host = this.#serverRelativeBaseUrl.host;
556
+ parsedUrl.protocol = this.#serverRelativeBaseUrl.protocol;
557
+ serverRelativeUrl = parsedUrl.href;
538
558
  }
539
559
  if (payload.params.url.match(/^[0-9a-z]+$/)) {
540
560
  payload.params.url = FILE_PREFIX + payload.params.url;
@@ -609,37 +629,44 @@ class Device {
609
629
  }
610
630
  }
611
631
  #processDebuggerSetBreakpointByUrl(req, debuggerInfo) {
612
- if (debuggerInfo.originalSourceURLAddress != null) {
613
- const processedReq = {
614
- ...req,
615
- params: {
616
- ...req.params,
617
- },
618
- };
619
- if (processedReq.params.url != null) {
620
- processedReq.params.url = processedReq.params.url.replace(
621
- "localhost",
622
- debuggerInfo.originalSourceURLAddress
623
- );
624
- if (
625
- processedReq.params.url &&
626
- processedReq.params.url.startsWith(FILE_PREFIX) &&
627
- debuggerInfo.prependedFilePrefix
628
- ) {
629
- processedReq.params.url = processedReq.params.url.slice(
630
- FILE_PREFIX.length
631
- );
632
- }
633
- }
634
- if (processedReq.params.urlRegex != null) {
635
- processedReq.params.urlRegex = processedReq.params.urlRegex.replace(
636
- /localhost/g,
637
- debuggerInfo.originalSourceURLAddress
632
+ const {
633
+ debuggerRelativeBaseUrl,
634
+ originalSourceURLOrigin,
635
+ prependedFilePrefix,
636
+ } = debuggerInfo;
637
+ const processedReq = {
638
+ ...req,
639
+ params: {
640
+ ...req.params,
641
+ },
642
+ };
643
+ if (originalSourceURLOrigin != null && processedReq.params.url != null) {
644
+ processedReq.params.url = processedReq.params.url.replace(
645
+ debuggerRelativeBaseUrl.origin,
646
+ originalSourceURLOrigin
647
+ );
648
+ if (
649
+ processedReq.params.url &&
650
+ processedReq.params.url.startsWith(FILE_PREFIX) &&
651
+ prependedFilePrefix
652
+ ) {
653
+ processedReq.params.url = processedReq.params.url.slice(
654
+ FILE_PREFIX.length
638
655
  );
639
656
  }
640
- return processedReq;
641
657
  }
642
- return req;
658
+ if (
659
+ REWRITE_HOSTS_TO_LOCALHOST.has(this.#deviceRelativeBaseUrl.hostname) &&
660
+ this.#deviceRelativeBaseUrl.port === debuggerRelativeBaseUrl.port &&
661
+ debuggerRelativeBaseUrl.hostname === "localhost" &&
662
+ processedReq.params.urlRegex != null
663
+ ) {
664
+ processedReq.params.urlRegex = processedReq.params.urlRegex.replaceAll(
665
+ "localhost",
666
+ this.#deviceRelativeBaseUrl.hostname.replaceAll(".", "\\.")
667
+ );
668
+ }
669
+ return processedReq;
643
670
  }
644
671
  #processDebuggerGetScriptSource(req, socket) {
645
672
  const sendSuccessResponse = (scriptSource) => {
@@ -23,6 +23,7 @@ export type DeviceOptions = $ReadOnly<{
23
23
  projectRoot: string,
24
24
  eventReporter: ?EventReporter,
25
25
  createMessageMiddleware: ?CreateCustomMessageHandlerFn,
26
+ deviceRelativeBaseUrl: URL,
26
27
  serverRelativeBaseUrl: URL,
27
28
  }>;
28
29
 
@@ -39,7 +40,8 @@ declare export default class Device {
39
40
  handleDebuggerConnection(
40
41
  socket: WS,
41
42
  pageId: string,
42
- metadata: $ReadOnly<{
43
+ $ReadOnly<{
44
+ debuggerRelativeBaseUrl: URL,
43
45
  userAgent: string | null,
44
46
  }>
45
47
  ): void;
@@ -141,6 +141,8 @@ class InspectorProxy {
141
141
  const deviceId = query.device || fallbackDeviceId;
142
142
  const deviceName = query.name || "Unknown";
143
143
  const appName = query.app || "Unknown";
144
+ const deviceRelativeBaseUrl =
145
+ (0, _getBaseUrlFromRequest.default)(req) ?? this.#serverBaseUrl;
144
146
  const oldDevice = this.#devices.get(deviceId);
145
147
  let newDevice;
146
148
  const deviceOptions = {
@@ -151,6 +153,7 @@ class InspectorProxy {
151
153
  projectRoot: this.#projectRoot,
152
154
  eventReporter: this.#eventReporter,
153
155
  createMessageMiddleware: this.#customMessageHandler,
156
+ deviceRelativeBaseUrl,
154
157
  serverRelativeBaseUrl: this.#serverBaseUrl,
155
158
  };
156
159
  if (oldDevice) {
@@ -161,7 +164,7 @@ class InspectorProxy {
161
164
  }
162
165
  this.#devices.set(deviceId, newDevice);
163
166
  debug(
164
- `Got new connection: name=${deviceName}, app=${appName}, device=${deviceId}`
167
+ `Got new connection: name=${deviceName}, app=${appName}, device=${deviceId}, via=${deviceRelativeBaseUrl.origin}`
165
168
  );
166
169
  socket.on("close", () => {
167
170
  if (this.#devices.get(deviceId)?.dangerouslyGetSocket() === socket) {
@@ -187,6 +190,8 @@ class InspectorProxy {
187
190
  const query = _url.default.parse(req.url || "", true).query || {};
188
191
  const deviceId = query.device;
189
192
  const pageId = query.page;
193
+ const debuggerRelativeBaseUrl =
194
+ (0, _getBaseUrlFromRequest.default)(req) ?? this.#serverBaseUrl;
190
195
  if (deviceId == null || pageId == null) {
191
196
  throw new Error("Incorrect URL - must provide device and page IDs");
192
197
  }
@@ -196,6 +201,7 @@ class InspectorProxy {
196
201
  }
197
202
  this.#startHeartbeat(socket, DEBUGGER_HEARTBEAT_INTERVAL_MS);
198
203
  device.handleDebuggerConnection(socket, pageId, {
204
+ debuggerRelativeBaseUrl,
199
205
  userAgent: req.headers["user-agent"] ?? query.userAgent ?? null,
200
206
  });
201
207
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native/dev-middleware",
3
- "version": "0.77.0-nightly-20241120-a865975ce",
3
+ "version": "0.77.0-nightly-20241122-e4d8c9678",
4
4
  "description": "Dev server middleware for React Native",
5
5
  "keywords": [
6
6
  "react-native",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@isaacs/ttlcache": "^1.4.1",
26
- "@react-native/debugger-frontend": "0.77.0-nightly-20241120-a865975ce",
26
+ "@react-native/debugger-frontend": "0.77.0-nightly-20241122-e4d8c9678",
27
27
  "chrome-launcher": "^0.15.2",
28
28
  "chromium-edge-launcher": "^0.2.0",
29
29
  "connect": "^3.6.5",