@react-native/dev-middleware 0.74.0 → 0.74.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/dist/createDevMiddleware.d.ts +8 -1
- package/dist/createDevMiddleware.js +12 -9
- package/dist/createDevMiddleware.js.flow +9 -1
- package/dist/index.flow.d.ts +2 -0
- package/dist/index.flow.js +16 -0
- package/dist/index.flow.js.flow +3 -0
- package/dist/inspector-proxy/Device.d.ts +3 -55
- package/dist/inspector-proxy/Device.js +254 -166
- package/dist/inspector-proxy/Device.js.flow +3 -59
- package/dist/inspector-proxy/DeviceEventReporter.d.ts +2 -12
- package/dist/inspector-proxy/DeviceEventReporter.js +37 -35
- package/dist/inspector-proxy/DeviceEventReporter.js.flow +2 -17
- package/dist/inspector-proxy/InspectorProxy.d.ts +1 -24
- package/dist/inspector-proxy/InspectorProxy.js +41 -30
- package/dist/inspector-proxy/InspectorProxy.js.flow +1 -24
- package/dist/inspector-proxy/cdp-types/messages.d.ts +39 -0
- package/dist/inspector-proxy/cdp-types/messages.js +1 -0
- package/dist/inspector-proxy/cdp-types/messages.js.flow +52 -0
- package/dist/inspector-proxy/cdp-types/protocol.d.ts +87 -0
- package/dist/inspector-proxy/cdp-types/protocol.js +1 -0
- package/dist/inspector-proxy/cdp-types/protocol.js.flow +106 -0
- package/dist/inspector-proxy/types.d.ts +60 -45
- package/dist/inspector-proxy/types.js.flow +62 -70
- package/dist/middleware/deprecated_openFlipperMiddleware.d.ts +1 -1
- package/dist/middleware/deprecated_openFlipperMiddleware.js.flow +1 -2
- package/dist/middleware/openDebuggerMiddleware.d.ts +1 -1
- package/dist/middleware/openDebuggerMiddleware.js +23 -8
- package/dist/middleware/openDebuggerMiddleware.js.flow +1 -2
- package/dist/types/EventReporter.d.ts +3 -3
- package/dist/types/EventReporter.js.flow +1 -1
- package/dist/types/Experiments.d.ts +4 -0
- package/dist/types/Experiments.js.flow +5 -0
- package/dist/utils/DefaultBrowserLauncher.js +1 -1
- package/dist/utils/getDevToolsFrontendUrl.d.ts +2 -0
- package/dist/utils/getDevToolsFrontendUrl.js +20 -4
- package/dist/utils/getDevToolsFrontendUrl.js.flow +3 -0
- package/package.json +13 -5
|
@@ -9,47 +9,16 @@
|
|
|
9
9
|
* @oncall react_native
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type {
|
|
13
|
-
DebuggerRequest,
|
|
14
|
-
GetScriptSourceRequest,
|
|
15
|
-
MessageFromDevice,
|
|
16
|
-
MessageToDevice,
|
|
17
|
-
Page,
|
|
18
|
-
SetBreakpointByUrlRequest,
|
|
19
|
-
} from "./types";
|
|
20
|
-
|
|
21
|
-
import DeviceEventReporter from "./DeviceEventReporter";
|
|
22
|
-
import WS from "ws";
|
|
23
12
|
import type { EventReporter } from "../types/EventReporter";
|
|
13
|
+
import type { Page } from "./types";
|
|
24
14
|
|
|
25
|
-
|
|
26
|
-
// Debugger web socket connection
|
|
27
|
-
socket: WS,
|
|
28
|
-
// If we replaced address (like '10.0.2.2') to localhost we need to store original
|
|
29
|
-
// address because Chrome uses URL or urlRegex params (instead of scriptId) to set breakpoints.
|
|
30
|
-
originalSourceURLAddress?: string,
|
|
31
|
-
prependedFilePrefix: boolean,
|
|
32
|
-
pageId: string,
|
|
33
|
-
userAgent: string | null,
|
|
34
|
-
};
|
|
15
|
+
import WS from "ws";
|
|
35
16
|
|
|
36
17
|
/**
|
|
37
18
|
* Device class represents single device connection to Inspector Proxy. Each device
|
|
38
19
|
* can have multiple inspectable pages.
|
|
39
20
|
*/
|
|
40
21
|
declare export default class Device {
|
|
41
|
-
_id: string;
|
|
42
|
-
_name: string;
|
|
43
|
-
_app: string;
|
|
44
|
-
_deviceSocket: WS;
|
|
45
|
-
_pages: Array<Page>;
|
|
46
|
-
_debuggerConnection: ?DebuggerInfo;
|
|
47
|
-
_lastConnectedReactNativePage: ?Page;
|
|
48
|
-
_isReloading: boolean;
|
|
49
|
-
_lastGetPagesMessage: string;
|
|
50
|
-
_scriptIdToSourcePathMapping: Map<string, string>;
|
|
51
|
-
_projectRoot: string;
|
|
52
|
-
_deviceEventReporter: ?DeviceEventReporter;
|
|
53
22
|
constructor(
|
|
54
23
|
id: string,
|
|
55
24
|
name: string,
|
|
@@ -60,7 +29,7 @@ declare export default class Device {
|
|
|
60
29
|
): void;
|
|
61
30
|
getName(): string;
|
|
62
31
|
getApp(): string;
|
|
63
|
-
getPagesList():
|
|
32
|
+
getPagesList(): $ReadOnlyArray<Page>;
|
|
64
33
|
handleDebuggerConnection(
|
|
65
34
|
socket: WS,
|
|
66
35
|
pageId: string,
|
|
@@ -69,29 +38,4 @@ declare export default class Device {
|
|
|
69
38
|
}>
|
|
70
39
|
): void;
|
|
71
40
|
handleDuplicateDeviceConnection(newDevice: Device): void;
|
|
72
|
-
_handleMessageFromDevice(message: MessageFromDevice): void;
|
|
73
|
-
_sendMessageToDevice(message: MessageToDevice): void;
|
|
74
|
-
_setPagesPolling(): void;
|
|
75
|
-
_newReactNativePage(page: Page): void;
|
|
76
|
-
_processMessageFromDevice(
|
|
77
|
-
payload: { method: string, params: { sourceMapURL: string, url: string } },
|
|
78
|
-
debuggerInfo: DebuggerInfo
|
|
79
|
-
): void;
|
|
80
|
-
_interceptMessageFromDebugger(
|
|
81
|
-
req: DebuggerRequest,
|
|
82
|
-
debuggerInfo: DebuggerInfo,
|
|
83
|
-
socket: WS
|
|
84
|
-
): boolean;
|
|
85
|
-
_processDebuggerSetBreakpointByUrl(
|
|
86
|
-
req: SetBreakpointByUrlRequest,
|
|
87
|
-
debuggerInfo: DebuggerInfo
|
|
88
|
-
): void;
|
|
89
|
-
_processDebuggerGetScriptSource(
|
|
90
|
-
req: GetScriptSourceRequest,
|
|
91
|
-
socket: WS
|
|
92
|
-
): void;
|
|
93
|
-
_mapToDevicePageId(pageId: string): string;
|
|
94
|
-
_tryParseHTTPURL(url: string): ?URL;
|
|
95
|
-
_fetchText(url: URL): Promise<string>;
|
|
96
|
-
_sendErrorToDebugger(message: string): void;
|
|
97
41
|
}
|
|
@@ -9,13 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { EventReporter } from "../types/EventReporter";
|
|
12
|
-
import
|
|
13
|
-
type PendingCommand = {
|
|
14
|
-
method: string;
|
|
15
|
-
requestOrigin: "proxy" | "debugger";
|
|
16
|
-
requestTime: number;
|
|
17
|
-
metadata: RequestMetadata;
|
|
18
|
-
};
|
|
12
|
+
import type { CDPResponse } from "./cdp-types/messages";
|
|
19
13
|
type DeviceMetadata = Readonly<{
|
|
20
14
|
appId: string;
|
|
21
15
|
deviceId: string;
|
|
@@ -26,9 +20,6 @@ type RequestMetadata = Readonly<{
|
|
|
26
20
|
frontendUserAgent: string | null;
|
|
27
21
|
}>;
|
|
28
22
|
declare class DeviceEventReporter {
|
|
29
|
-
_eventReporter: EventReporter;
|
|
30
|
-
_pendingCommands: TTLCache<number, PendingCommand>;
|
|
31
|
-
_metadata: DeviceMetadata;
|
|
32
23
|
constructor(eventReporter: EventReporter, metadata: DeviceMetadata);
|
|
33
24
|
logRequest(
|
|
34
25
|
req: Readonly<{ id: number; method: string }>,
|
|
@@ -36,7 +27,7 @@ declare class DeviceEventReporter {
|
|
|
36
27
|
metadata: RequestMetadata
|
|
37
28
|
): void;
|
|
38
29
|
logResponse(
|
|
39
|
-
res:
|
|
30
|
+
res: CDPResponse<>,
|
|
40
31
|
origin: "device" | "proxy",
|
|
41
32
|
metadata: Readonly<{
|
|
42
33
|
pageId: string | null;
|
|
@@ -48,7 +39,6 @@ declare class DeviceEventReporter {
|
|
|
48
39
|
metadata: Readonly<{ pageId: string; frontendUserAgent: string | null }>
|
|
49
40
|
): void;
|
|
50
41
|
logDisconnection(disconnectedEntity: "device" | "debugger"): void;
|
|
51
|
-
_logExpiredCommand(pendingCommand: PendingCommand): void;
|
|
52
42
|
}
|
|
53
43
|
declare const $$EXPORT_DEFAULT_DECLARATION$$: typeof DeviceEventReporter;
|
|
54
44
|
export default $$EXPORT_DEFAULT_DECLARATION$$;
|
|
@@ -19,22 +19,24 @@ function _interopRequireDefault(obj) {
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
class DeviceEventReporter {
|
|
22
|
-
|
|
22
|
+
#eventReporter;
|
|
23
|
+
#pendingCommands = new _ttlcache.default({
|
|
23
24
|
ttl: 10000,
|
|
24
25
|
dispose: (command, id, reason) => {
|
|
25
26
|
if (reason === "delete" || reason === "set") {
|
|
26
27
|
// TODO: Report clobbering ('set') using a dedicated error code
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
|
-
this
|
|
30
|
+
this.#logExpiredCommand(command);
|
|
30
31
|
},
|
|
31
32
|
});
|
|
33
|
+
#metadata;
|
|
32
34
|
constructor(eventReporter, metadata) {
|
|
33
|
-
this
|
|
34
|
-
this
|
|
35
|
+
this.#eventReporter = eventReporter;
|
|
36
|
+
this.#metadata = metadata;
|
|
35
37
|
}
|
|
36
38
|
logRequest(req, origin, metadata) {
|
|
37
|
-
this.
|
|
39
|
+
this.#pendingCommands.set(req.id, {
|
|
38
40
|
method: req.method,
|
|
39
41
|
requestOrigin: origin,
|
|
40
42
|
requestTime: Date.now(),
|
|
@@ -42,9 +44,9 @@ class DeviceEventReporter {
|
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
logResponse(res, origin, metadata) {
|
|
45
|
-
const pendingCommand = this.
|
|
47
|
+
const pendingCommand = this.#pendingCommands.get(res.id);
|
|
46
48
|
if (!pendingCommand) {
|
|
47
|
-
this.
|
|
49
|
+
this.#eventReporter.logEvent({
|
|
48
50
|
type: "debugger_command",
|
|
49
51
|
protocol: "CDP",
|
|
50
52
|
requestOrigin: null,
|
|
@@ -53,22 +55,22 @@ class DeviceEventReporter {
|
|
|
53
55
|
errorCode: "UNMATCHED_REQUEST_ID",
|
|
54
56
|
responseOrigin: "proxy",
|
|
55
57
|
timeSinceStart: null,
|
|
56
|
-
appId: this.
|
|
57
|
-
deviceId: this.
|
|
58
|
-
deviceName: this.
|
|
58
|
+
appId: this.#metadata.appId,
|
|
59
|
+
deviceId: this.#metadata.deviceId,
|
|
60
|
+
deviceName: this.#metadata.deviceName,
|
|
59
61
|
pageId: metadata.pageId,
|
|
60
62
|
frontendUserAgent: metadata.frontendUserAgent,
|
|
61
63
|
});
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
66
|
const timeSinceStart = Date.now() - pendingCommand.requestTime;
|
|
65
|
-
this.
|
|
67
|
+
this.#pendingCommands.delete(res.id);
|
|
66
68
|
if (res.error) {
|
|
67
69
|
let { message } = res.error;
|
|
68
70
|
if ("data" in res.error) {
|
|
69
71
|
message += ` (${String(res.error.data)})`;
|
|
70
72
|
}
|
|
71
|
-
this.
|
|
73
|
+
this.#eventReporter.logEvent({
|
|
72
74
|
type: "debugger_command",
|
|
73
75
|
requestOrigin: pendingCommand.requestOrigin,
|
|
74
76
|
method: pendingCommand.method,
|
|
@@ -78,15 +80,15 @@ class DeviceEventReporter {
|
|
|
78
80
|
errorDetails: message,
|
|
79
81
|
responseOrigin: origin,
|
|
80
82
|
timeSinceStart,
|
|
81
|
-
appId: this.
|
|
82
|
-
deviceId: this.
|
|
83
|
-
deviceName: this.
|
|
83
|
+
appId: this.#metadata.appId,
|
|
84
|
+
deviceId: this.#metadata.deviceId,
|
|
85
|
+
deviceName: this.#metadata.deviceName,
|
|
84
86
|
pageId: pendingCommand.metadata.pageId,
|
|
85
87
|
frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
|
|
86
88
|
});
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
|
-
this.
|
|
91
|
+
this.#eventReporter.logEvent({
|
|
90
92
|
type: "debugger_command",
|
|
91
93
|
protocol: "CDP",
|
|
92
94
|
requestOrigin: pendingCommand.requestOrigin,
|
|
@@ -94,26 +96,26 @@ class DeviceEventReporter {
|
|
|
94
96
|
status: "success",
|
|
95
97
|
responseOrigin: origin,
|
|
96
98
|
timeSinceStart,
|
|
97
|
-
appId: this.
|
|
98
|
-
deviceId: this.
|
|
99
|
-
deviceName: this.
|
|
99
|
+
appId: this.#metadata.appId,
|
|
100
|
+
deviceId: this.#metadata.deviceId,
|
|
101
|
+
deviceName: this.#metadata.deviceName,
|
|
100
102
|
pageId: pendingCommand.metadata.pageId,
|
|
101
103
|
frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
|
|
102
104
|
});
|
|
103
105
|
}
|
|
104
106
|
logConnection(connectedEntity, metadata) {
|
|
105
|
-
this.
|
|
107
|
+
this.#eventReporter.logEvent({
|
|
106
108
|
type: "connect_debugger_frontend",
|
|
107
109
|
status: "success",
|
|
108
|
-
appId: this.
|
|
109
|
-
deviceName: this.
|
|
110
|
-
deviceId: this.
|
|
110
|
+
appId: this.#metadata.appId,
|
|
111
|
+
deviceName: this.#metadata.deviceName,
|
|
112
|
+
deviceId: this.#metadata.deviceId,
|
|
111
113
|
pageId: metadata.pageId,
|
|
112
114
|
frontendUserAgent: metadata.frontendUserAgent,
|
|
113
115
|
});
|
|
114
116
|
}
|
|
115
117
|
logDisconnection(disconnectedEntity) {
|
|
116
|
-
const eventReporter = this
|
|
118
|
+
const eventReporter = this.#eventReporter;
|
|
117
119
|
if (!eventReporter) {
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
@@ -121,8 +123,8 @@ class DeviceEventReporter {
|
|
|
121
123
|
disconnectedEntity === "device"
|
|
122
124
|
? "DEVICE_DISCONNECTED"
|
|
123
125
|
: "DEBUGGER_DISCONNECTED";
|
|
124
|
-
for (const pendingCommand of this.
|
|
125
|
-
this.
|
|
126
|
+
for (const pendingCommand of this.#pendingCommands.values()) {
|
|
127
|
+
this.#eventReporter.logEvent({
|
|
126
128
|
type: "debugger_command",
|
|
127
129
|
protocol: "CDP",
|
|
128
130
|
requestOrigin: pendingCommand.requestOrigin,
|
|
@@ -131,17 +133,17 @@ class DeviceEventReporter {
|
|
|
131
133
|
errorCode,
|
|
132
134
|
responseOrigin: "proxy",
|
|
133
135
|
timeSinceStart: Date.now() - pendingCommand.requestTime,
|
|
134
|
-
appId: this.
|
|
135
|
-
deviceId: this.
|
|
136
|
-
deviceName: this.
|
|
136
|
+
appId: this.#metadata.appId,
|
|
137
|
+
deviceId: this.#metadata.deviceId,
|
|
138
|
+
deviceName: this.#metadata.deviceName,
|
|
137
139
|
pageId: pendingCommand.metadata.pageId,
|
|
138
140
|
frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
|
-
this.
|
|
143
|
+
this.#pendingCommands.clear();
|
|
142
144
|
}
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
+
#logExpiredCommand(pendingCommand) {
|
|
146
|
+
this.#eventReporter.logEvent({
|
|
145
147
|
type: "debugger_command",
|
|
146
148
|
protocol: "CDP",
|
|
147
149
|
requestOrigin: pendingCommand.requestOrigin,
|
|
@@ -150,9 +152,9 @@ class DeviceEventReporter {
|
|
|
150
152
|
errorCode: "TIMED_OUT",
|
|
151
153
|
responseOrigin: "proxy",
|
|
152
154
|
timeSinceStart: Date.now() - pendingCommand.requestTime,
|
|
153
|
-
appId: this.
|
|
154
|
-
deviceId: this.
|
|
155
|
-
deviceName: this.
|
|
155
|
+
appId: this.#metadata.appId,
|
|
156
|
+
deviceId: this.#metadata.deviceId,
|
|
157
|
+
deviceName: this.#metadata.deviceName,
|
|
156
158
|
pageId: pendingCommand.metadata.pageId,
|
|
157
159
|
frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
|
|
158
160
|
});
|
|
@@ -9,14 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { EventReporter } from "../types/EventReporter";
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
type PendingCommand = {
|
|
15
|
-
method: string,
|
|
16
|
-
requestOrigin: "proxy" | "debugger",
|
|
17
|
-
requestTime: number,
|
|
18
|
-
metadata: RequestMetadata,
|
|
19
|
-
};
|
|
12
|
+
import type { CDPResponse } from "./cdp-types/messages";
|
|
20
13
|
|
|
21
14
|
type DeviceMetadata = $ReadOnly<{
|
|
22
15
|
appId: string,
|
|
@@ -30,9 +23,6 @@ type RequestMetadata = $ReadOnly<{
|
|
|
30
23
|
}>;
|
|
31
24
|
|
|
32
25
|
declare class DeviceEventReporter {
|
|
33
|
-
_eventReporter: EventReporter;
|
|
34
|
-
_pendingCommands: TTLCache<number, PendingCommand>;
|
|
35
|
-
_metadata: DeviceMetadata;
|
|
36
26
|
constructor(eventReporter: EventReporter, metadata: DeviceMetadata): void;
|
|
37
27
|
logRequest(
|
|
38
28
|
req: $ReadOnly<{ id: number, method: string, ... }>,
|
|
@@ -40,11 +30,7 @@ declare class DeviceEventReporter {
|
|
|
40
30
|
metadata: RequestMetadata
|
|
41
31
|
): void;
|
|
42
32
|
logResponse(
|
|
43
|
-
res:
|
|
44
|
-
id: number,
|
|
45
|
-
error?: { message: string, data?: mixed },
|
|
46
|
-
...
|
|
47
|
-
}>,
|
|
33
|
+
res: CDPResponse<>,
|
|
48
34
|
origin: "device" | "proxy",
|
|
49
35
|
metadata: $ReadOnly<{
|
|
50
36
|
pageId: string | null,
|
|
@@ -59,7 +45,6 @@ declare class DeviceEventReporter {
|
|
|
59
45
|
}>
|
|
60
46
|
): void;
|
|
61
47
|
logDisconnection(disconnectedEntity: "device" | "debugger"): void;
|
|
62
|
-
_logExpiredCommand(pendingCommand: PendingCommand): void;
|
|
63
48
|
}
|
|
64
49
|
|
|
65
50
|
declare export default typeof DeviceEventReporter;
|
|
@@ -9,17 +9,11 @@
|
|
|
9
9
|
* @oncall react_native
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type {
|
|
13
|
-
JsonPagesListResponse,
|
|
14
|
-
JsonVersionResponse,
|
|
15
|
-
Page,
|
|
16
|
-
PageDescription,
|
|
17
|
-
} from "./types";
|
|
18
12
|
import type { EventReporter } from "../types/EventReporter";
|
|
19
13
|
import type { Experiments } from "../types/Experiments";
|
|
14
|
+
import type { PageDescription } from "./types";
|
|
20
15
|
import type { IncomingMessage, ServerResponse } from "http";
|
|
21
16
|
import WS from "ws";
|
|
22
|
-
import Device from "./Device";
|
|
23
17
|
export interface InspectorProxyQueries {
|
|
24
18
|
getPageDescriptions(): Array<PageDescription>;
|
|
25
19
|
}
|
|
@@ -27,12 +21,6 @@ export interface InspectorProxyQueries {
|
|
|
27
21
|
* Main Inspector Proxy class that connects JavaScript VM inside Android/iOS apps and JS debugger.
|
|
28
22
|
*/
|
|
29
23
|
declare class InspectorProxy implements InspectorProxyQueries {
|
|
30
|
-
_projectRoot: string;
|
|
31
|
-
_serverBaseUrl: string;
|
|
32
|
-
_devices: Map<string, Device>;
|
|
33
|
-
_deviceCounter: number;
|
|
34
|
-
_eventReporter: null | undefined | EventReporter;
|
|
35
|
-
_experiments: Experiments;
|
|
36
24
|
constructor(
|
|
37
25
|
projectRoot: string,
|
|
38
26
|
serverBaseUrl: string,
|
|
@@ -46,16 +34,5 @@ declare class InspectorProxy implements InspectorProxyQueries {
|
|
|
46
34
|
next: ($$PARAM_0$$: null | undefined | Error) => unknown
|
|
47
35
|
): void;
|
|
48
36
|
createWebSocketListeners(): { [path: string]: WS.Server };
|
|
49
|
-
_buildPageDescription(
|
|
50
|
-
deviceId: string,
|
|
51
|
-
device: Device,
|
|
52
|
-
page: Page
|
|
53
|
-
): PageDescription;
|
|
54
|
-
_sendJsonResponse(
|
|
55
|
-
response: ServerResponse,
|
|
56
|
-
object: JsonPagesListResponse | JsonVersionResponse
|
|
57
|
-
): void;
|
|
58
|
-
_createDeviceConnectionWSServer(): ws$WebSocketServer;
|
|
59
|
-
_createDebuggerConnectionWSServer(): ws$WebSocketServer;
|
|
60
37
|
}
|
|
61
38
|
export default InspectorProxy;
|
|
@@ -4,9 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true,
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
var _Device = _interopRequireDefault(require("./Device"));
|
|
8
|
+
var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
|
7
9
|
var _url = _interopRequireDefault(require("url"));
|
|
8
10
|
var _ws = _interopRequireDefault(require("ws"));
|
|
9
|
-
var _Device = _interopRequireDefault(require("./Device"));
|
|
10
11
|
function _interopRequireDefault(obj) {
|
|
11
12
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
12
13
|
}
|
|
@@ -33,28 +34,33 @@ const INTERNAL_ERROR_CODE = 1011;
|
|
|
33
34
|
*/
|
|
34
35
|
class InspectorProxy {
|
|
35
36
|
// Root of the project used for relative to absolute source path conversion.
|
|
37
|
+
#projectRoot;
|
|
36
38
|
|
|
37
39
|
/** The base URL to the dev server from the developer machine. */
|
|
40
|
+
#serverBaseUrl;
|
|
38
41
|
|
|
39
42
|
// Maps device ID to Device instance.
|
|
43
|
+
#devices;
|
|
40
44
|
|
|
41
45
|
// Internal counter for device IDs -- just gets incremented for each new device.
|
|
42
|
-
|
|
46
|
+
#deviceCounter = 0;
|
|
47
|
+
#eventReporter;
|
|
48
|
+
#experiments;
|
|
43
49
|
constructor(projectRoot, serverBaseUrl, eventReporter, experiments) {
|
|
44
|
-
this
|
|
45
|
-
this
|
|
46
|
-
this
|
|
47
|
-
this
|
|
48
|
-
this
|
|
50
|
+
this.#projectRoot = projectRoot;
|
|
51
|
+
this.#serverBaseUrl = serverBaseUrl;
|
|
52
|
+
this.#devices = new Map();
|
|
53
|
+
this.#eventReporter = eventReporter;
|
|
54
|
+
this.#experiments = experiments;
|
|
49
55
|
}
|
|
50
56
|
getPageDescriptions() {
|
|
51
57
|
// Build list of pages from all devices.
|
|
52
58
|
let result = [];
|
|
53
|
-
Array.from(this.
|
|
59
|
+
Array.from(this.#devices.entries()).forEach(([deviceId, device]) => {
|
|
54
60
|
result = result.concat(
|
|
55
61
|
device
|
|
56
62
|
.getPagesList()
|
|
57
|
-
.map((page) => this
|
|
63
|
+
.map((page) => this.#buildPageDescription(deviceId, device, page))
|
|
58
64
|
);
|
|
59
65
|
});
|
|
60
66
|
return result;
|
|
@@ -65,13 +71,14 @@ class InspectorProxy {
|
|
|
65
71
|
// 2. /json and /json/list returns list of page descriptions (list of inspectable apps).
|
|
66
72
|
// This list is combined from all the connected devices.
|
|
67
73
|
processRequest(request, response, next) {
|
|
74
|
+
const pathname = _url.default.parse(request.url).pathname;
|
|
68
75
|
if (
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
pathname === PAGES_LIST_JSON_URL ||
|
|
77
|
+
pathname === PAGES_LIST_JSON_URL_2
|
|
71
78
|
) {
|
|
72
|
-
this
|
|
73
|
-
} else if (
|
|
74
|
-
this
|
|
79
|
+
this.#sendJsonResponse(response, this.getPageDescriptions());
|
|
80
|
+
} else if (pathname === PAGES_LIST_JSON_VERSION_URL) {
|
|
81
|
+
this.#sendJsonResponse(response, {
|
|
75
82
|
Browser: "Mobile JavaScript",
|
|
76
83
|
"Protocol-Version": "1.1",
|
|
77
84
|
});
|
|
@@ -81,15 +88,15 @@ class InspectorProxy {
|
|
|
81
88
|
}
|
|
82
89
|
createWebSocketListeners() {
|
|
83
90
|
return {
|
|
84
|
-
[WS_DEVICE_URL]: this
|
|
85
|
-
[WS_DEBUGGER_URL]: this
|
|
91
|
+
[WS_DEVICE_URL]: this.#createDeviceConnectionWSServer(),
|
|
92
|
+
[WS_DEBUGGER_URL]: this.#createDebuggerConnectionWSServer(),
|
|
86
93
|
};
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
// Converts page information received from device into PageDescription object
|
|
90
97
|
// that is sent to debugger.
|
|
91
|
-
|
|
92
|
-
const { host, protocol } = new URL(this
|
|
98
|
+
#buildPageDescription(deviceId, device, page) {
|
|
99
|
+
const { host, protocol } = new URL(this.#serverBaseUrl);
|
|
93
100
|
const webSocketScheme = protocol === "https:" ? "wss" : "ws";
|
|
94
101
|
const webSocketUrlWithoutProtocol = `${host}${WS_DEBUGGER_URL}?device=${deviceId}&page=${page.id}`;
|
|
95
102
|
// For now, `/json/list` returns the legacy built-in `devtools://` URL, to
|
|
@@ -108,17 +115,21 @@ class InspectorProxy {
|
|
|
108
115
|
webSocketDebuggerUrl: `${webSocketScheme}://${webSocketUrlWithoutProtocol}`,
|
|
109
116
|
vm: page.vm,
|
|
110
117
|
deviceName: device.getName(),
|
|
118
|
+
reactNative: {
|
|
119
|
+
logicalDeviceId: deviceId,
|
|
120
|
+
capabilities: (0, _nullthrows.default)(page.capabilities),
|
|
121
|
+
},
|
|
111
122
|
};
|
|
112
123
|
}
|
|
113
124
|
|
|
114
125
|
// Sends object as response to HTTP request.
|
|
115
126
|
// Just serializes object using JSON and sets required headers.
|
|
116
|
-
|
|
127
|
+
#sendJsonResponse(response, object) {
|
|
117
128
|
const data = JSON.stringify(object, null, 2);
|
|
118
129
|
response.writeHead(200, {
|
|
119
130
|
"Content-Type": "application/json; charset=UTF-8",
|
|
120
131
|
"Cache-Control": "no-cache",
|
|
121
|
-
"Content-Length": data.
|
|
132
|
+
"Content-Length": Buffer.byteLength(data).toString(),
|
|
122
133
|
Connection: "close",
|
|
123
134
|
});
|
|
124
135
|
response.end(data);
|
|
@@ -129,7 +140,7 @@ class InspectorProxy {
|
|
|
129
140
|
// HTTP GET params.
|
|
130
141
|
// For each new websocket connection we parse device and app names and create
|
|
131
142
|
// new instance of Device class.
|
|
132
|
-
|
|
143
|
+
#createDeviceConnectionWSServer() {
|
|
133
144
|
const wss = new _ws.default.Server({
|
|
134
145
|
noServer: true,
|
|
135
146
|
perMessageDeflate: true,
|
|
@@ -140,29 +151,29 @@ class InspectorProxy {
|
|
|
140
151
|
// $FlowFixMe[value-as-type]
|
|
141
152
|
wss.on("connection", async (socket, req) => {
|
|
142
153
|
try {
|
|
143
|
-
const fallbackDeviceId = String(this
|
|
154
|
+
const fallbackDeviceId = String(this.#deviceCounter++);
|
|
144
155
|
const query = _url.default.parse(req.url || "", true).query || {};
|
|
145
156
|
const deviceId = query.device || fallbackDeviceId;
|
|
146
157
|
const deviceName = query.name || "Unknown";
|
|
147
158
|
const appName = query.app || "Unknown";
|
|
148
|
-
const oldDevice = this.
|
|
159
|
+
const oldDevice = this.#devices.get(deviceId);
|
|
149
160
|
const newDevice = new _Device.default(
|
|
150
161
|
deviceId,
|
|
151
162
|
deviceName,
|
|
152
163
|
appName,
|
|
153
164
|
socket,
|
|
154
|
-
this
|
|
155
|
-
this
|
|
165
|
+
this.#projectRoot,
|
|
166
|
+
this.#eventReporter
|
|
156
167
|
);
|
|
157
168
|
if (oldDevice) {
|
|
158
169
|
oldDevice.handleDuplicateDeviceConnection(newDevice);
|
|
159
170
|
}
|
|
160
|
-
this.
|
|
171
|
+
this.#devices.set(deviceId, newDevice);
|
|
161
172
|
debug(
|
|
162
173
|
`Got new connection: name=${deviceName}, app=${appName}, device=${deviceId}`
|
|
163
174
|
);
|
|
164
175
|
socket.on("close", () => {
|
|
165
|
-
this.
|
|
176
|
+
this.#devices.delete(deviceId);
|
|
166
177
|
debug(`Device ${deviceName} disconnected.`);
|
|
167
178
|
});
|
|
168
179
|
} catch (e) {
|
|
@@ -178,7 +189,7 @@ class InspectorProxy {
|
|
|
178
189
|
// in /json response.
|
|
179
190
|
// When debugger connects we try to parse device and page IDs from the query and pass
|
|
180
191
|
// websocket object to corresponding Device instance.
|
|
181
|
-
|
|
192
|
+
#createDebuggerConnectionWSServer() {
|
|
182
193
|
const wss = new _ws.default.Server({
|
|
183
194
|
noServer: true,
|
|
184
195
|
perMessageDeflate: false,
|
|
@@ -195,7 +206,7 @@ class InspectorProxy {
|
|
|
195
206
|
if (deviceId == null || pageId == null) {
|
|
196
207
|
throw new Error("Incorrect URL - must provide device and page IDs");
|
|
197
208
|
}
|
|
198
|
-
const device = this.
|
|
209
|
+
const device = this.#devices.get(deviceId);
|
|
199
210
|
if (device == null) {
|
|
200
211
|
throw new Error("Unknown device with ID " + deviceId);
|
|
201
212
|
}
|
|
@@ -205,7 +216,7 @@ class InspectorProxy {
|
|
|
205
216
|
} catch (e) {
|
|
206
217
|
console.error(e);
|
|
207
218
|
socket.close(INTERNAL_ERROR_CODE, e?.toString() ?? "Unknown error");
|
|
208
|
-
this
|
|
219
|
+
this.#eventReporter?.logEvent({
|
|
209
220
|
type: "connect_debugger_frontend",
|
|
210
221
|
status: "error",
|
|
211
222
|
error: e,
|
|
@@ -9,18 +9,12 @@
|
|
|
9
9
|
* @oncall react_native
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type {
|
|
13
|
-
JsonPagesListResponse,
|
|
14
|
-
JsonVersionResponse,
|
|
15
|
-
Page,
|
|
16
|
-
PageDescription,
|
|
17
|
-
} from "./types";
|
|
18
12
|
import type { EventReporter } from "../types/EventReporter";
|
|
19
13
|
import type { Experiments } from "../types/Experiments";
|
|
14
|
+
import type { PageDescription } from "./types";
|
|
20
15
|
import type { IncomingMessage, ServerResponse } from "http";
|
|
21
16
|
|
|
22
17
|
import WS from "ws";
|
|
23
|
-
import Device from "./Device";
|
|
24
18
|
|
|
25
19
|
export interface InspectorProxyQueries {
|
|
26
20
|
getPageDescriptions(): Array<PageDescription>;
|
|
@@ -30,12 +24,6 @@ export interface InspectorProxyQueries {
|
|
|
30
24
|
* Main Inspector Proxy class that connects JavaScript VM inside Android/iOS apps and JS debugger.
|
|
31
25
|
*/
|
|
32
26
|
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
27
|
constructor(
|
|
40
28
|
projectRoot: string,
|
|
41
29
|
serverBaseUrl: string,
|
|
@@ -51,15 +39,4 @@ declare export default class InspectorProxy implements InspectorProxyQueries {
|
|
|
51
39
|
createWebSocketListeners(): {
|
|
52
40
|
[path: string]: WS.Server,
|
|
53
41
|
};
|
|
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
42
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { Commands, Events } from "./protocol";
|
|
13
|
+
export type CDPEvent<TEvent extends keyof Events = "unknown"> = Readonly<{
|
|
14
|
+
method: TEvent;
|
|
15
|
+
params: Events[TEvent];
|
|
16
|
+
}>;
|
|
17
|
+
export type CDPRequest<TCommand extends keyof Commands = "unknown"> = Readonly<{
|
|
18
|
+
method: TCommand;
|
|
19
|
+
params: Commands[TCommand]["paramsType"];
|
|
20
|
+
id: number;
|
|
21
|
+
}>;
|
|
22
|
+
export type CDPResponse<TCommand extends keyof Commands = "unknown"> =
|
|
23
|
+
| Readonly<{ result: Commands[TCommand]["resultType"]; id: number }>
|
|
24
|
+
| Readonly<{ error: CDPRequestError; id: number }>;
|
|
25
|
+
export type CDPRequestError = Readonly<{
|
|
26
|
+
code: number;
|
|
27
|
+
message: string;
|
|
28
|
+
data?: unknown;
|
|
29
|
+
}>;
|
|
30
|
+
export type CDPClientMessage =
|
|
31
|
+
| CDPRequest<"Debugger.getScriptSource">
|
|
32
|
+
| CDPRequest<"Debugger.scriptParsed">
|
|
33
|
+
| CDPRequest<"Debugger.setBreakpointByUrl">
|
|
34
|
+
| CDPRequest<>;
|
|
35
|
+
export type CDPServerMessage =
|
|
36
|
+
| CDPEvent<"Debugger.scriptParsed">
|
|
37
|
+
| CDPEvent<>
|
|
38
|
+
| CDPResponse<"Debugger.getScriptSource">
|
|
39
|
+
| CDPResponse<>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|