@react-native/dev-middleware 0.73.0 → 0.73.2
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.
- package/README.md +77 -3
- package/dist/createDevMiddleware.d.ts +53 -0
- package/dist/createDevMiddleware.js +53 -6
- package/dist/createDevMiddleware.js.flow +44 -15
- package/dist/index.d.ts +12 -0
- package/dist/index.flow.d.ts +14 -0
- package/dist/index.flow.js.flow +5 -2
- package/dist/index.js +14 -1
- package/dist/index.js.flow +1 -9
- package/dist/inspector-proxy/Device.d.ts +90 -0
- package/dist/inspector-proxy/Device.js +708 -0
- package/dist/inspector-proxy/Device.js.flow +97 -0
- package/dist/inspector-proxy/DeviceEventReporter.d.ts +53 -0
- package/dist/inspector-proxy/DeviceEventReporter.js +162 -0
- package/dist/inspector-proxy/DeviceEventReporter.js.flow +65 -0
- package/dist/inspector-proxy/InspectorProxy.d.ts +61 -0
- package/dist/inspector-proxy/InspectorProxy.js +212 -0
- package/dist/inspector-proxy/InspectorProxy.js.flow +65 -0
- package/dist/inspector-proxy/types.d.ts +78 -0
- package/dist/inspector-proxy/types.js +1 -0
- package/dist/inspector-proxy/types.js.flow +135 -0
- package/dist/middleware/openDebuggerMiddleware.d.ts +37 -0
- package/dist/middleware/openDebuggerMiddleware.js +78 -24
- package/dist/middleware/openDebuggerMiddleware.js.flow +15 -64
- package/dist/types/BrowserLauncher.d.ts +27 -0
- package/dist/types/BrowserLauncher.js +1 -0
- package/dist/types/BrowserLauncher.js.flow +31 -0
- package/dist/types/EventReporter.d.ts +69 -0
- package/dist/types/EventReporter.js +1 -0
- package/dist/types/EventReporter.js.flow +81 -0
- package/dist/types/Experiments.d.ts +25 -0
- package/dist/types/Experiments.js +1 -0
- package/dist/types/Experiments.js.flow +27 -0
- package/dist/types/Logger.d.ts +16 -0
- package/dist/utils/DefaultBrowserLauncher.d.ts +18 -0
- package/dist/utils/DefaultBrowserLauncher.js +77 -0
- package/dist/utils/DefaultBrowserLauncher.js.flow +20 -0
- package/dist/utils/getDevToolsFrontendUrl.d.ts +21 -0
- package/dist/utils/getDevToolsFrontendUrl.js +48 -0
- package/dist/utils/getDevToolsFrontendUrl.js.flow +21 -0
- package/package.json +6 -1
- package/dist/utils/getDevServerUrl.js +0 -37
- package/dist/utils/getDevServerUrl.js.flow +0 -32
- package/dist/utils/launchChromeDevTools.js +0 -44
- package/dist/utils/launchChromeDevTools.js.flow +0 -38
- package/dist/utils/launchDebuggerAppWindow.js +0 -58
- package/dist/utils/launchDebuggerAppWindow.js.flow +0 -56
- package/dist/utils/queryInspectorTargets.js +0 -35
- package/dist/utils/queryInspectorTargets.js.flow +0 -40
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
JsonPagesListResponse,
|
|
14
|
+
JsonVersionResponse,
|
|
15
|
+
Page,
|
|
16
|
+
PageDescription,
|
|
17
|
+
} from "./types";
|
|
18
|
+
import type { EventReporter } from "../types/EventReporter";
|
|
19
|
+
import type { Experiments } from "../types/Experiments";
|
|
20
|
+
import type { IncomingMessage, ServerResponse } from "http";
|
|
21
|
+
|
|
22
|
+
import WS from "ws";
|
|
23
|
+
import Device from "./Device";
|
|
24
|
+
|
|
25
|
+
export interface InspectorProxyQueries {
|
|
26
|
+
getPageDescriptions(): Array<PageDescription>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Main Inspector Proxy class that connects JavaScript VM inside Android/iOS apps and JS debugger.
|
|
31
|
+
*/
|
|
32
|
+
declare export default class InspectorProxy implements InspectorProxyQueries {
|
|
33
|
+
_projectRoot: string;
|
|
34
|
+
_serverBaseUrl: string;
|
|
35
|
+
_devices: Map<string, Device>;
|
|
36
|
+
_deviceCounter: number;
|
|
37
|
+
_eventReporter: ?EventReporter;
|
|
38
|
+
_experiments: Experiments;
|
|
39
|
+
constructor(
|
|
40
|
+
projectRoot: string,
|
|
41
|
+
serverBaseUrl: string,
|
|
42
|
+
eventReporter: ?EventReporter,
|
|
43
|
+
experiments: Experiments
|
|
44
|
+
): void;
|
|
45
|
+
getPageDescriptions(): Array<PageDescription>;
|
|
46
|
+
processRequest(
|
|
47
|
+
request: IncomingMessage,
|
|
48
|
+
response: ServerResponse,
|
|
49
|
+
next: (?Error) => mixed
|
|
50
|
+
): void;
|
|
51
|
+
createWebSocketListeners(): {
|
|
52
|
+
[path: string]: WS.Server,
|
|
53
|
+
};
|
|
54
|
+
_buildPageDescription(
|
|
55
|
+
deviceId: string,
|
|
56
|
+
device: Device,
|
|
57
|
+
page: Page
|
|
58
|
+
): PageDescription;
|
|
59
|
+
_sendJsonResponse(
|
|
60
|
+
response: ServerResponse,
|
|
61
|
+
object: JsonPagesListResponse | JsonVersionResponse
|
|
62
|
+
): void;
|
|
63
|
+
_createDeviceConnectionWSServer(): ws$WebSocketServer;
|
|
64
|
+
_createDebuggerConnectionWSServer(): ws$WebSocketServer;
|
|
65
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export type Page = { id: string; title: string; vm: string; app: string };
|
|
13
|
+
export type WrappedEvent = {
|
|
14
|
+
event: "wrappedEvent";
|
|
15
|
+
payload: { pageId: string; wrappedEvent: string };
|
|
16
|
+
};
|
|
17
|
+
export type ConnectRequest = { event: "connect"; payload: { pageId: string } };
|
|
18
|
+
export type DisconnectRequest = {
|
|
19
|
+
event: "disconnect";
|
|
20
|
+
payload: { pageId: string };
|
|
21
|
+
};
|
|
22
|
+
export type GetPagesRequest = { event: "getPages" };
|
|
23
|
+
export type GetPagesResponse = { event: "getPages"; payload: Array<Page> };
|
|
24
|
+
export type MessageFromDevice =
|
|
25
|
+
| GetPagesResponse
|
|
26
|
+
| WrappedEvent
|
|
27
|
+
| DisconnectRequest;
|
|
28
|
+
export type MessageToDevice =
|
|
29
|
+
| GetPagesRequest
|
|
30
|
+
| WrappedEvent
|
|
31
|
+
| ConnectRequest
|
|
32
|
+
| DisconnectRequest;
|
|
33
|
+
export type PageDescription = {
|
|
34
|
+
id: string;
|
|
35
|
+
description: string;
|
|
36
|
+
title: string;
|
|
37
|
+
faviconUrl: string;
|
|
38
|
+
devtoolsFrontendUrl: string;
|
|
39
|
+
type: string;
|
|
40
|
+
webSocketDebuggerUrl: string;
|
|
41
|
+
};
|
|
42
|
+
export type JsonPagesListResponse = Array<PageDescription>;
|
|
43
|
+
export type JsonVersionResponse = {
|
|
44
|
+
Browser: string;
|
|
45
|
+
"Protocol-Version": string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Types were exported from https://github.com/ChromeDevTools/devtools-protocol/blob/master/types/protocol.d.ts
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
export type SetBreakpointByUrlRequest = {
|
|
52
|
+
id: number;
|
|
53
|
+
method: "Debugger.setBreakpointByUrl";
|
|
54
|
+
params: {
|
|
55
|
+
lineNumber: number;
|
|
56
|
+
url?: string;
|
|
57
|
+
urlRegex?: string;
|
|
58
|
+
scriptHash?: string;
|
|
59
|
+
columnNumber?: number;
|
|
60
|
+
condition?: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export type GetScriptSourceRequest = {
|
|
64
|
+
id: number;
|
|
65
|
+
method: "Debugger.getScriptSource";
|
|
66
|
+
params: { scriptId: string };
|
|
67
|
+
};
|
|
68
|
+
export type GetScriptSourceResponse = {
|
|
69
|
+
scriptSource: string;
|
|
70
|
+
/**
|
|
71
|
+
* Wasm bytecode.
|
|
72
|
+
*/
|
|
73
|
+
bytecode?: string;
|
|
74
|
+
};
|
|
75
|
+
export type ErrorResponse = { error: { message: string } };
|
|
76
|
+
export type DebuggerRequest =
|
|
77
|
+
| SetBreakpointByUrlRequest
|
|
78
|
+
| GetScriptSourceRequest;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Page information received from the device. New page is created for
|
|
13
|
+
// each new instance of VM and can appear when user reloads React Native
|
|
14
|
+
// application.
|
|
15
|
+
export type Page = {
|
|
16
|
+
id: string,
|
|
17
|
+
title: string,
|
|
18
|
+
vm: string,
|
|
19
|
+
app: string,
|
|
20
|
+
...
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Chrome Debugger Protocol message/event passed between device and debugger.
|
|
24
|
+
export type WrappedEvent = {
|
|
25
|
+
event: "wrappedEvent",
|
|
26
|
+
payload: {
|
|
27
|
+
pageId: string,
|
|
28
|
+
wrappedEvent: string,
|
|
29
|
+
...
|
|
30
|
+
},
|
|
31
|
+
...
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Request sent from Inspector Proxy to Device when new debugger is connected
|
|
35
|
+
// to particular page.
|
|
36
|
+
export type ConnectRequest = {
|
|
37
|
+
event: "connect",
|
|
38
|
+
payload: { pageId: string, ... },
|
|
39
|
+
...
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Request sent from Inspector Proxy to Device to notify that debugger is
|
|
43
|
+
// disconnected.
|
|
44
|
+
export type DisconnectRequest = {
|
|
45
|
+
event: "disconnect",
|
|
46
|
+
payload: { pageId: string, ... },
|
|
47
|
+
...
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// Request sent from Inspector Proxy to Device to get a list of pages.
|
|
51
|
+
export type GetPagesRequest = { event: "getPages", ... };
|
|
52
|
+
|
|
53
|
+
// Response to GetPagesRequest containing a list of page infos.
|
|
54
|
+
export type GetPagesResponse = {
|
|
55
|
+
event: "getPages",
|
|
56
|
+
payload: Array<Page>,
|
|
57
|
+
...
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Union type for all possible messages sent from device to Inspector Proxy.
|
|
61
|
+
export type MessageFromDevice =
|
|
62
|
+
| GetPagesResponse
|
|
63
|
+
| WrappedEvent
|
|
64
|
+
| DisconnectRequest;
|
|
65
|
+
|
|
66
|
+
// Union type for all possible messages sent from Inspector Proxy to device.
|
|
67
|
+
export type MessageToDevice =
|
|
68
|
+
| GetPagesRequest
|
|
69
|
+
| WrappedEvent
|
|
70
|
+
| ConnectRequest
|
|
71
|
+
| DisconnectRequest;
|
|
72
|
+
|
|
73
|
+
// Page description object that is sent in response to /json HTTP request from debugger.
|
|
74
|
+
export type PageDescription = {
|
|
75
|
+
id: string,
|
|
76
|
+
description: string,
|
|
77
|
+
title: string,
|
|
78
|
+
faviconUrl: string,
|
|
79
|
+
devtoolsFrontendUrl: string,
|
|
80
|
+
type: string,
|
|
81
|
+
webSocketDebuggerUrl: string,
|
|
82
|
+
...
|
|
83
|
+
};
|
|
84
|
+
export type JsonPagesListResponse = Array<PageDescription>;
|
|
85
|
+
|
|
86
|
+
// Response to /json/version HTTP request from the debugger specifying browser type and
|
|
87
|
+
// Chrome protocol version.
|
|
88
|
+
export type JsonVersionResponse = {
|
|
89
|
+
Browser: string,
|
|
90
|
+
"Protocol-Version": string,
|
|
91
|
+
...
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Types were exported from https://github.com/ChromeDevTools/devtools-protocol/blob/master/types/protocol.d.ts
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
export type SetBreakpointByUrlRequest = {
|
|
99
|
+
id: number,
|
|
100
|
+
method: "Debugger.setBreakpointByUrl",
|
|
101
|
+
params: {
|
|
102
|
+
lineNumber: number,
|
|
103
|
+
url?: string,
|
|
104
|
+
urlRegex?: string,
|
|
105
|
+
scriptHash?: string,
|
|
106
|
+
columnNumber?: number,
|
|
107
|
+
condition?: string,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export type GetScriptSourceRequest = {
|
|
112
|
+
id: number,
|
|
113
|
+
method: "Debugger.getScriptSource",
|
|
114
|
+
params: {
|
|
115
|
+
scriptId: string,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type GetScriptSourceResponse = {
|
|
120
|
+
scriptSource: string,
|
|
121
|
+
/**
|
|
122
|
+
* Wasm bytecode.
|
|
123
|
+
*/
|
|
124
|
+
bytecode?: string,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export type ErrorResponse = {
|
|
128
|
+
error: {
|
|
129
|
+
message: string,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export type DebuggerRequest =
|
|
134
|
+
| SetBreakpointByUrlRequest
|
|
135
|
+
| GetScriptSourceRequest;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { NextHandleFunction } from "connect";
|
|
13
|
+
import type { InspectorProxyQueries } from "../inspector-proxy/InspectorProxy";
|
|
14
|
+
import type { BrowserLauncher } from "../types/BrowserLauncher";
|
|
15
|
+
import type { EventReporter } from "../types/EventReporter";
|
|
16
|
+
import type { Experiments } from "../types/Experiments";
|
|
17
|
+
import type { Logger } from "../types/Logger";
|
|
18
|
+
type Options = Readonly<{
|
|
19
|
+
serverBaseUrl: string;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
browserLauncher: BrowserLauncher;
|
|
22
|
+
eventReporter?: EventReporter;
|
|
23
|
+
experiments: Experiments;
|
|
24
|
+
inspectorProxy: InspectorProxyQueries;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Open the JavaScript debugger for a given CDP target (direct Hermes debugging).
|
|
28
|
+
*
|
|
29
|
+
* Currently supports Hermes targets, opening debugger websocket URL in Chrome
|
|
30
|
+
* DevTools.
|
|
31
|
+
*
|
|
32
|
+
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
33
|
+
*/
|
|
34
|
+
declare function openDebuggerMiddleware(
|
|
35
|
+
$$PARAM_0$$: Options
|
|
36
|
+
): NextHandleFunction;
|
|
37
|
+
export default openDebuggerMiddleware;
|
|
@@ -5,14 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = openDebuggerMiddleware;
|
|
7
7
|
var _url = _interopRequireDefault(require("url"));
|
|
8
|
-
var
|
|
9
|
-
require("../utils/
|
|
10
|
-
);
|
|
11
|
-
var _launchChromeDevTools = _interopRequireDefault(
|
|
12
|
-
require("../utils/launchChromeDevTools")
|
|
13
|
-
);
|
|
14
|
-
var _queryInspectorTargets = _interopRequireDefault(
|
|
15
|
-
require("../utils/queryInspectorTargets")
|
|
8
|
+
var _getDevToolsFrontendUrl = _interopRequireDefault(
|
|
9
|
+
require("../utils/getDevToolsFrontendUrl")
|
|
16
10
|
);
|
|
17
11
|
function _interopRequireDefault(obj) {
|
|
18
12
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
@@ -37,36 +31,90 @@ const debuggerInstances = new Map();
|
|
|
37
31
|
*
|
|
38
32
|
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
39
33
|
*/
|
|
40
|
-
function openDebuggerMiddleware({
|
|
34
|
+
function openDebuggerMiddleware({
|
|
35
|
+
serverBaseUrl,
|
|
36
|
+
logger,
|
|
37
|
+
browserLauncher,
|
|
38
|
+
eventReporter,
|
|
39
|
+
experiments,
|
|
40
|
+
inspectorProxy,
|
|
41
|
+
}) {
|
|
41
42
|
return async (req, res, next) => {
|
|
42
|
-
if (
|
|
43
|
+
if (
|
|
44
|
+
req.method === "POST" ||
|
|
45
|
+
(experiments.enableOpenDebuggerRedirect && req.method === "GET")
|
|
46
|
+
) {
|
|
43
47
|
const { query } = _url.default.parse(req.url, true);
|
|
44
48
|
const { appId } = query;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
const targets = await (0, _queryInspectorTargets.default)(
|
|
51
|
-
(0, _getDevServerUrl.default)(req)
|
|
49
|
+
const targets = inspectorProxy.getPageDescriptions().filter(
|
|
50
|
+
// Only use targets with better reloading support
|
|
51
|
+
(app) =>
|
|
52
|
+
app.title === "React Native Experimental (Improved Chrome Reloads)"
|
|
52
53
|
);
|
|
53
|
-
|
|
54
|
+
let target;
|
|
55
|
+
const launchType = req.method === "POST" ? "launch" : "redirect";
|
|
56
|
+
if (typeof appId === "string") {
|
|
57
|
+
logger?.info(
|
|
58
|
+
(launchType === "launch" ? "Launching" : "Redirecting to") +
|
|
59
|
+
" JS debugger..."
|
|
60
|
+
);
|
|
61
|
+
target = targets.find((_target) => _target.description === appId);
|
|
62
|
+
} else {
|
|
63
|
+
logger?.info(
|
|
64
|
+
(launchType === "launch" ? "Launching" : "Redirecting to") +
|
|
65
|
+
" JS debugger for first available target..."
|
|
66
|
+
);
|
|
67
|
+
target = targets[0];
|
|
68
|
+
}
|
|
54
69
|
if (!target) {
|
|
55
70
|
res.writeHead(404);
|
|
56
71
|
res.end("Unable to find Chrome DevTools inspector target");
|
|
57
72
|
logger?.warn(
|
|
58
73
|
"No compatible apps connected. JavaScript debugging can only be used with the Hermes engine."
|
|
59
74
|
);
|
|
75
|
+
eventReporter?.logEvent({
|
|
76
|
+
type: "launch_debugger_frontend",
|
|
77
|
+
launchType,
|
|
78
|
+
status: "coded_error",
|
|
79
|
+
errorCode: "NO_APPS_FOUND",
|
|
80
|
+
});
|
|
60
81
|
return;
|
|
61
82
|
}
|
|
62
83
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
switch (launchType) {
|
|
85
|
+
case "launch":
|
|
86
|
+
await debuggerInstances.get(appId)?.kill();
|
|
87
|
+
debuggerInstances.set(
|
|
88
|
+
appId,
|
|
89
|
+
await browserLauncher.launchDebuggerAppWindow(
|
|
90
|
+
(0, _getDevToolsFrontendUrl.default)(
|
|
91
|
+
target.webSocketDebuggerUrl,
|
|
92
|
+
serverBaseUrl,
|
|
93
|
+
experiments
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
res.end();
|
|
98
|
+
break;
|
|
99
|
+
case "redirect":
|
|
100
|
+
res.writeHead(302, {
|
|
101
|
+
Location: (0, _getDevToolsFrontendUrl.default)(
|
|
102
|
+
target.webSocketDebuggerUrl,
|
|
103
|
+
// Use a relative URL.
|
|
104
|
+
"",
|
|
105
|
+
experiments
|
|
106
|
+
),
|
|
107
|
+
});
|
|
108
|
+
res.end();
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
}
|
|
112
|
+
eventReporter?.logEvent({
|
|
113
|
+
type: "launch_debugger_frontend",
|
|
114
|
+
launchType,
|
|
115
|
+
status: "success",
|
|
66
116
|
appId,
|
|
67
|
-
|
|
68
|
-
);
|
|
69
|
-
res.end();
|
|
117
|
+
});
|
|
70
118
|
return;
|
|
71
119
|
} catch (e) {
|
|
72
120
|
logger?.error(
|
|
@@ -74,6 +122,12 @@ function openDebuggerMiddleware({ logger }) {
|
|
|
74
122
|
);
|
|
75
123
|
res.writeHead(500);
|
|
76
124
|
res.end();
|
|
125
|
+
eventReporter?.logEvent({
|
|
126
|
+
type: "launch_debugger_frontend",
|
|
127
|
+
launchType,
|
|
128
|
+
status: "error",
|
|
129
|
+
error: e,
|
|
130
|
+
});
|
|
77
131
|
return;
|
|
78
132
|
}
|
|
79
133
|
}
|
|
@@ -4,25 +4,25 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @flow strict
|
|
7
|
+
* @flow strict-local
|
|
8
8
|
* @format
|
|
9
9
|
* @oncall react_native
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type {
|
|
13
|
-
import type {
|
|
14
|
-
import type {
|
|
15
|
-
import type {
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
import getDevServerUrl from '../utils/getDevServerUrl';
|
|
19
|
-
import launchChromeDevTools from '../utils/launchChromeDevTools';
|
|
20
|
-
import queryInspectorTargets from '../utils/queryInspectorTargets';
|
|
21
|
-
|
|
22
|
-
const debuggerInstances = new Map<string, LaunchedChrome>();
|
|
12
|
+
import type { NextHandleFunction } from "connect";
|
|
13
|
+
import type { InspectorProxyQueries } from "../inspector-proxy/InspectorProxy";
|
|
14
|
+
import type { BrowserLauncher } from "../types/BrowserLauncher";
|
|
15
|
+
import type { EventReporter } from "../types/EventReporter";
|
|
16
|
+
import type { Experiments } from "../types/Experiments";
|
|
17
|
+
import type { Logger } from "../types/Logger";
|
|
23
18
|
|
|
24
19
|
type Options = $ReadOnly<{
|
|
20
|
+
serverBaseUrl: string,
|
|
25
21
|
logger?: Logger,
|
|
22
|
+
browserLauncher: BrowserLauncher,
|
|
23
|
+
eventReporter?: EventReporter,
|
|
24
|
+
experiments: Experiments,
|
|
25
|
+
inspectorProxy: InspectorProxyQueries,
|
|
26
26
|
}>;
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -33,55 +33,6 @@ type Options = $ReadOnly<{
|
|
|
33
33
|
*
|
|
34
34
|
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
35
35
|
*/
|
|
36
|
-
export default function openDebuggerMiddleware(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return async (
|
|
40
|
-
req: IncomingMessage,
|
|
41
|
-
res: ServerResponse,
|
|
42
|
-
next: (err?: Error) => void,
|
|
43
|
-
) => {
|
|
44
|
-
if (req.method === 'POST') {
|
|
45
|
-
const {query} = url.parse(req.url, true);
|
|
46
|
-
const {appId} = query;
|
|
47
|
-
|
|
48
|
-
if (typeof appId !== 'string') {
|
|
49
|
-
res.writeHead(400);
|
|
50
|
-
res.end();
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const targets = await queryInspectorTargets(getDevServerUrl(req));
|
|
55
|
-
const target = targets.find(_target => _target.description === appId);
|
|
56
|
-
|
|
57
|
-
if (!target) {
|
|
58
|
-
res.writeHead(404);
|
|
59
|
-
res.end('Unable to find Chrome DevTools inspector target');
|
|
60
|
-
logger?.warn(
|
|
61
|
-
'No compatible apps connected. JavaScript debugging can only be used with the Hermes engine.',
|
|
62
|
-
);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
logger?.info('Launching JS debugger...');
|
|
68
|
-
debuggerInstances.get(appId)?.kill();
|
|
69
|
-
debuggerInstances.set(
|
|
70
|
-
appId,
|
|
71
|
-
await launchChromeDevTools(target.webSocketDebuggerUrl),
|
|
72
|
-
);
|
|
73
|
-
res.end();
|
|
74
|
-
return;
|
|
75
|
-
} catch (e) {
|
|
76
|
-
logger?.error(
|
|
77
|
-
'Error launching JS debugger: ' + e.message ?? 'Unknown error',
|
|
78
|
-
);
|
|
79
|
-
res.writeHead(500);
|
|
80
|
-
res.end();
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
next();
|
|
86
|
-
};
|
|
87
|
-
}
|
|
36
|
+
declare export default function openDebuggerMiddleware(
|
|
37
|
+
Options
|
|
38
|
+
): NextHandleFunction;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Represents a launched web browser instance.
|
|
14
|
+
*/
|
|
15
|
+
export type LaunchedBrowser = { kill: () => void | Promise<void> };
|
|
16
|
+
/**
|
|
17
|
+
* An interface for integrators to provide a custom implementation for
|
|
18
|
+
* opening URLs in a web browser.
|
|
19
|
+
*/
|
|
20
|
+
export interface BrowserLauncher {
|
|
21
|
+
/**
|
|
22
|
+
* Attempt to open a debugger frontend URL in a browser app window,
|
|
23
|
+
* optionally returning an object to control the launched browser instance.
|
|
24
|
+
* The browser used should be capable of running Chrome DevTools.
|
|
25
|
+
*/
|
|
26
|
+
launchDebuggerAppWindow: (url: string) => Promise<LaunchedBrowser | void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Represents a launched web browser instance.
|
|
14
|
+
*/
|
|
15
|
+
export type LaunchedBrowser = {
|
|
16
|
+
kill: () => void | Promise<void>,
|
|
17
|
+
...
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* An interface for integrators to provide a custom implementation for
|
|
22
|
+
* opening URLs in a web browser.
|
|
23
|
+
*/
|
|
24
|
+
export interface BrowserLauncher {
|
|
25
|
+
/**
|
|
26
|
+
* Attempt to open a debugger frontend URL in a browser app window,
|
|
27
|
+
* optionally returning an object to control the launched browser instance.
|
|
28
|
+
* The browser used should be capable of running Chrome DevTools.
|
|
29
|
+
*/
|
|
30
|
+
launchDebuggerAppWindow: (url: string) => Promise<LaunchedBrowser | void>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
type SuccessResult<Props extends {} | void = {}> =
|
|
12
|
+
/**
|
|
13
|
+
* > 13 | ...Props,
|
|
14
|
+
* | ^^^^^^^^ Unsupported feature: Translating "object types with spreads in the middle or at the end" is currently not supported.
|
|
15
|
+
**/
|
|
16
|
+
any;
|
|
17
|
+
type ErrorResult<ErrorT = unknown> = { status: "error"; error: ErrorT };
|
|
18
|
+
type CodedErrorResult<ErrorCode extends string> = {
|
|
19
|
+
status: "coded_error";
|
|
20
|
+
errorCode: ErrorCode;
|
|
21
|
+
errorDetails?: string;
|
|
22
|
+
};
|
|
23
|
+
type DebuggerSessionIDs = {
|
|
24
|
+
appId: string;
|
|
25
|
+
deviceName: string;
|
|
26
|
+
deviceId: string;
|
|
27
|
+
pageId: string | null;
|
|
28
|
+
};
|
|
29
|
+
export type ReportableEvent =
|
|
30
|
+
| /**
|
|
31
|
+
* > 38 | ...
|
|
32
|
+
* | ^^^
|
|
33
|
+
* > 39 | | SuccessResult<{ appId: string }>
|
|
34
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
35
|
+
* > 40 | | ErrorResult<mixed>
|
|
36
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
37
|
+
* > 41 | | CodedErrorResult<"NO_APPS_FOUND">,
|
|
38
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unsupported feature: Translating "object types with spreads in the middle or at the end" is currently not supported.
|
|
39
|
+
**/
|
|
40
|
+
any
|
|
41
|
+
| /**
|
|
42
|
+
* > 45 | ...
|
|
43
|
+
* | ^^^
|
|
44
|
+
* > 46 | | SuccessResult<{
|
|
45
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
46
|
+
* > 47 | ...DebuggerSessionIDs,
|
|
47
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
48
|
+
* > 48 | frontendUserAgent: string | null,
|
|
49
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
50
|
+
* > 49 | }>
|
|
51
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
52
|
+
* > 50 | | ErrorResult<mixed>,
|
|
53
|
+
* | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unsupported feature: Translating "object types with spreads in the middle or at the end" is currently not supported.
|
|
54
|
+
**/
|
|
55
|
+
any
|
|
56
|
+
| /**
|
|
57
|
+
* > 60 | ...DebuggerSessionIDs,
|
|
58
|
+
* | ^^^^^^^^^^^^^^^^^^^^^ Unsupported feature: Translating "object types with spreads in the middle or at the end" is currently not supported.
|
|
59
|
+
**/
|
|
60
|
+
any;
|
|
61
|
+
/**
|
|
62
|
+
* A simple interface for logging events, to be implemented by integrators of
|
|
63
|
+
* `dev-middleware`.
|
|
64
|
+
*
|
|
65
|
+
* This is an unstable API with no semver guarantees.
|
|
66
|
+
*/
|
|
67
|
+
export interface EventReporter {
|
|
68
|
+
logEvent(event: ReportableEvent): void;
|
|
69
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|