@expo/cli 0.6.2 → 0.7.1
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/build/bin/cli +3 -3
- package/build/bin/cli.map +1 -1
- package/build/src/start/interface/interactiveActions.js +30 -3
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/server/BundlerDevServer.js +5 -0
- package/build/src/start/server/BundlerDevServer.js.map +1 -1
- package/build/src/start/server/ReactDevToolsProxy.js +73 -0
- package/build/src/start/server/ReactDevToolsProxy.js.map +1 -0
- package/build/src/start/server/metro/MetroBundlerDevServer.js +3 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/inspector-proxy/device.js +72 -0
- package/build/src/start/server/metro/inspector-proxy/device.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/DebuggerScriptSource.js +87 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/DebuggerScriptSource.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/NetworkResponse.js +29 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/NetworkResponse.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/PageReload.js +22 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/PageReload.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/VscodeCompat.js +63 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/VscodeCompat.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/types.js +6 -0
- package/build/src/start/server/metro/inspector-proxy/handlers/types.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/index.js +27 -0
- package/build/src/start/server/metro/inspector-proxy/index.js.map +1 -0
- package/build/src/start/server/metro/inspector-proxy/proxy.js +145 -0
- package/build/src/start/server/metro/inspector-proxy/proxy.js.map +1 -0
- package/build/src/start/server/metro/instantiateMetro.js +18 -2
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/resolveFromProject.js +8 -0
- package/build/src/start/server/metro/resolveFromProject.js.map +1 -1
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js +2 -2
- package/build/src/start/server/middleware/ClassicManifestMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ManifestMiddleware.js +7 -0
- package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ReactDevToolsPageMiddleware.js +35 -0
- package/build/src/start/server/middleware/ReactDevToolsPageMiddleware.js.map +1 -0
- package/build/src/utils/analytics/rudderstackClient.js +2 -2
- package/build/src/utils/env.js +3 -0
- package/build/src/utils/env.js.map +1 -1
- package/package.json +8 -5
- package/static/react-devtools-page/index.html +144 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
exports.createInspectorDeviceClass = createInspectorDeviceClass;
|
|
6
|
+
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
7
|
+
var _debuggerScriptSource = require("./handlers/DebuggerScriptSource");
|
|
8
|
+
var _networkResponse = require("./handlers/NetworkResponse");
|
|
9
|
+
var _pageReload = require("./handlers/PageReload");
|
|
10
|
+
var _vscodeCompat = require("./handlers/VscodeCompat");
|
|
11
|
+
function _interopRequireDefault(obj) {
|
|
12
|
+
return obj && obj.__esModule ? obj : {
|
|
13
|
+
default: obj
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function createInspectorDeviceClass(metroBundler, MetroDeviceClass) {
|
|
17
|
+
return class ExpoInspectorDevice extends MetroDeviceClass {
|
|
18
|
+
/** All handlers that should be used to intercept or reply to CDP events */ handlers = [
|
|
19
|
+
new _networkResponse.NetworkResponseHandler(),
|
|
20
|
+
new _debuggerScriptSource.DebuggerScriptSourceHandler(this),
|
|
21
|
+
new _pageReload.PageReloadHandler(metroBundler),
|
|
22
|
+
new _vscodeCompat.VscodeCompatHandler(),
|
|
23
|
+
];
|
|
24
|
+
onDeviceMessage(message, info) {
|
|
25
|
+
var ref;
|
|
26
|
+
return this.handlers.some((handler)=>{
|
|
27
|
+
return (ref = handler.onDeviceMessage == null ? void 0 : handler.onDeviceMessage(message, info)) != null ? ref : false;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
onDebuggerMessage(message, info) {
|
|
31
|
+
var ref;
|
|
32
|
+
return this.handlers.some((handler)=>{
|
|
33
|
+
return (ref = handler.onDebuggerMessage == null ? void 0 : handler.onDebuggerMessage(message, info)) != null ? ref : false;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** Hook into the message life cycle to answer more complex CDP messages */ async _processMessageFromDevice(message, info) {
|
|
37
|
+
if (!this.onDeviceMessage(message, info)) {
|
|
38
|
+
await super._processMessageFromDevice(message, info);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Hook into the message life cycle to answer more complex CDP messages */ _interceptMessageFromDebugger(request, info, socket) {
|
|
42
|
+
// Note, `socket` is the exact same as `info.socket`
|
|
43
|
+
if (this.onDebuggerMessage(request, info)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return super._interceptMessageFromDebugger(request, info, socket);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Overwrite the default text fetcher, to load sourcemaps from sources other than `localhost`.
|
|
50
|
+
* @todo Cedric: remove the custom `DebuggerScriptSource` handler when switching over to `metro@>=0.75.1`
|
|
51
|
+
* @see https://github.com/facebook/metro/blob/77f445f1bcd2264ad06174dbf8d542bc75834d29/packages/metro-inspector-proxy/src/Device.js#L573-L588
|
|
52
|
+
* @since metro-inspector-proxy@0.75.1
|
|
53
|
+
*/ async _fetchText(url) {
|
|
54
|
+
const LENGTH_LIMIT_BYTES = 350000000; // 350mb
|
|
55
|
+
const response = await (0, _nodeFetch).default(url);
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
throw new Error(`Received status ${response.status} while fetching: ${url}`);
|
|
58
|
+
}
|
|
59
|
+
const contentLength = response.headers.get("Content-Length");
|
|
60
|
+
if (contentLength && Number(contentLength) > LENGTH_LIMIT_BYTES) {
|
|
61
|
+
throw new Error("Expected file size is too large (more than 350mb)");
|
|
62
|
+
}
|
|
63
|
+
const text = await response.text();
|
|
64
|
+
if (Buffer.byteLength(text, "utf8") > LENGTH_LIMIT_BYTES) {
|
|
65
|
+
throw new Error("File size is too large (more than 350mb)");
|
|
66
|
+
}
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/metro/inspector-proxy/device.ts"],"sourcesContent":["import type { DebuggerInfo, Device as MetroDevice } from 'metro-inspector-proxy';\nimport fetch from 'node-fetch';\nimport type WS from 'ws';\n\nimport { MetroBundlerDevServer } from '../MetroBundlerDevServer';\nimport { DebuggerScriptSourceHandler } from './handlers/DebuggerScriptSource';\nimport { NetworkResponseHandler } from './handlers/NetworkResponse';\nimport { PageReloadHandler } from './handlers/PageReload';\nimport { VscodeCompatHandler } from './handlers/VscodeCompat';\nimport { DeviceRequest, InspectorHandler, DebuggerRequest } from './handlers/types';\n\nexport function createInspectorDeviceClass(\n metroBundler: MetroBundlerDevServer,\n MetroDeviceClass: typeof MetroDevice\n) {\n return class ExpoInspectorDevice extends MetroDeviceClass implements InspectorHandler {\n /** All handlers that should be used to intercept or reply to CDP events */\n public handlers: InspectorHandler[] = [\n new NetworkResponseHandler(),\n new DebuggerScriptSourceHandler(this),\n new PageReloadHandler(metroBundler),\n new VscodeCompatHandler(),\n ];\n\n onDeviceMessage(message: any, info: DebuggerInfo): boolean {\n return this.handlers.some((handler) => handler.onDeviceMessage?.(message, info) ?? false);\n }\n\n onDebuggerMessage(message: any, info: DebuggerInfo): boolean {\n return this.handlers.some((handler) => handler.onDebuggerMessage?.(message, info) ?? false);\n }\n\n /** Hook into the message life cycle to answer more complex CDP messages */\n async _processMessageFromDevice(message: DeviceRequest<any>, info: DebuggerInfo) {\n if (!this.onDeviceMessage(message, info)) {\n await super._processMessageFromDevice(message, info);\n }\n }\n\n /** Hook into the message life cycle to answer more complex CDP messages */\n _interceptMessageFromDebugger(\n request: DebuggerRequest,\n info: DebuggerInfo,\n socket: WS\n ): boolean {\n // Note, `socket` is the exact same as `info.socket`\n if (this.onDebuggerMessage(request, info)) {\n return true;\n }\n\n return super._interceptMessageFromDebugger(request, info, socket);\n }\n\n /**\n * Overwrite the default text fetcher, to load sourcemaps from sources other than `localhost`.\n * @todo Cedric: remove the custom `DebuggerScriptSource` handler when switching over to `metro@>=0.75.1`\n * @see https://github.com/facebook/metro/blob/77f445f1bcd2264ad06174dbf8d542bc75834d29/packages/metro-inspector-proxy/src/Device.js#L573-L588\n * @since metro-inspector-proxy@0.75.1\n */\n async _fetchText(url: URL): Promise<string> {\n const LENGTH_LIMIT_BYTES = 350_000_000; // 350mb\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Received status ${response.status} while fetching: ${url}`);\n }\n\n const contentLength = response.headers.get('Content-Length');\n if (contentLength && Number(contentLength) > LENGTH_LIMIT_BYTES) {\n throw new Error('Expected file size is too large (more than 350mb)');\n }\n\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > LENGTH_LIMIT_BYTES) {\n throw new Error('File size is too large (more than 350mb)');\n }\n\n return text;\n }\n };\n}\n"],"names":["createInspectorDeviceClass","metroBundler","MetroDeviceClass","ExpoInspectorDevice","handlers","NetworkResponseHandler","DebuggerScriptSourceHandler","PageReloadHandler","VscodeCompatHandler","onDeviceMessage","message","info","handler","some","onDebuggerMessage","_processMessageFromDevice","_interceptMessageFromDebugger","request","socket","_fetchText","url","LENGTH_LIMIT_BYTES","response","fetch","ok","Error","status","contentLength","headers","get","Number","text","Buffer","byteLength"],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
6
|
+
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
7
|
+
var _path = _interopRequireDefault(require("path"));
|
|
8
|
+
function _interopRequireDefault(obj) {
|
|
9
|
+
return obj && obj.__esModule ? obj : {
|
|
10
|
+
default: obj
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
class DebuggerScriptSourceHandler {
|
|
14
|
+
constructor(device){
|
|
15
|
+
this.device = device;
|
|
16
|
+
}
|
|
17
|
+
onDebuggerMessage(message, { socket }) {
|
|
18
|
+
// See: https://github.com/facebook/metro/blob/65d801cb60c06c1b17f428ca79491db73c53ef87/packages/metro-inspector-proxy/src/Device.js#L488-L544
|
|
19
|
+
if (message.method === "Debugger.getScriptSource") {
|
|
20
|
+
const { scriptId } = message.params;
|
|
21
|
+
const pathOrUrl = this.device._scriptIdToSourcePathMapping.get(scriptId);
|
|
22
|
+
// Unkown scriptId provided, can't reply
|
|
23
|
+
if (!pathOrUrl) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// Fetch the source from URL, if the path is a bundle URL
|
|
27
|
+
if (isUrl(pathOrUrl)) {
|
|
28
|
+
(0, _nodeFetch).default(pathOrUrl).then((response)=>response.ok ? response.text() : respond(socket, message, {
|
|
29
|
+
error: `Received status ${response.status} while fetching: ${pathOrUrl}`
|
|
30
|
+
})
|
|
31
|
+
).then((scriptSource)=>{
|
|
32
|
+
if (scriptSource !== null) {
|
|
33
|
+
respond(socket, message, {
|
|
34
|
+
scriptSource
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
// Fetch the source from file directly, using the project root as starting directory
|
|
41
|
+
try {
|
|
42
|
+
const relativePath = _path.default.resolve(this.device._projectRoot, pathOrUrl);
|
|
43
|
+
respond(socket, message, {
|
|
44
|
+
scriptSource: _fs.default.readFileSync(relativePath, "utf8")
|
|
45
|
+
});
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
48
|
+
respond(socket, message, {
|
|
49
|
+
error: `Failed to load "${pathOrUrl}": ${errorMessage}`
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.DebuggerScriptSourceHandler = DebuggerScriptSourceHandler;
|
|
58
|
+
function respond(socket, request, response) {
|
|
59
|
+
if ("error" in response) {
|
|
60
|
+
socket.send(JSON.stringify({
|
|
61
|
+
id: request.id,
|
|
62
|
+
error: {
|
|
63
|
+
message: response.error
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
} else {
|
|
67
|
+
socket.send(JSON.stringify({
|
|
68
|
+
id: request.id,
|
|
69
|
+
result: response
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
function isUrl(pathOrUrl) {
|
|
75
|
+
try {
|
|
76
|
+
const url = new URL(pathOrUrl);
|
|
77
|
+
return [
|
|
78
|
+
"http",
|
|
79
|
+
"https"
|
|
80
|
+
].some((protocol)=>url.protocol.toLowerCase().startsWith(protocol)
|
|
81
|
+
);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=DebuggerScriptSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/DebuggerScriptSource.ts"],"sourcesContent":["import type { Protocol } from 'devtools-protocol';\nimport fs from 'fs';\nimport type { DebuggerInfo, Device as MetroDevice } from 'metro-inspector-proxy';\nimport fetch from 'node-fetch';\nimport path from 'path';\nimport type WS from 'ws';\n\nimport { CdpMessage, DebuggerRequest, DebuggerResponse, InspectorHandler } from './types';\n\n// TODO(cedric): remove this custom handler when fully switching over to `metro@>=0.75.1`\nexport class DebuggerScriptSourceHandler implements InspectorHandler {\n constructor(private readonly device: MetroDevice) {}\n\n onDebuggerMessage(\n message: DebuggerRequest<DebuggerGetScriptSource>,\n { socket }: Pick<DebuggerInfo, 'socket'>\n ) {\n // See: https://github.com/facebook/metro/blob/65d801cb60c06c1b17f428ca79491db73c53ef87/packages/metro-inspector-proxy/src/Device.js#L488-L544\n if (message.method === 'Debugger.getScriptSource') {\n const { scriptId } = message.params;\n const pathOrUrl = this.device._scriptIdToSourcePathMapping.get(scriptId);\n\n // Unkown scriptId provided, can't reply\n if (!pathOrUrl) {\n return false;\n }\n\n // Fetch the source from URL, if the path is a bundle URL\n if (isUrl(pathOrUrl)) {\n fetch(pathOrUrl)\n .then((response) =>\n response.ok\n ? response.text()\n : respond(socket, message, {\n error: `Received status ${response.status} while fetching: ${pathOrUrl}`,\n })\n )\n .then((scriptSource) => {\n if (scriptSource !== null) {\n respond(socket, message, { scriptSource });\n }\n });\n\n return true;\n }\n\n // Fetch the source from file directly, using the project root as starting directory\n try {\n const relativePath = path.resolve(this.device._projectRoot, pathOrUrl);\n respond(socket, message, { scriptSource: fs.readFileSync(relativePath, 'utf8') });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n respond(socket, message, {\n error: `Failed to load \"${pathOrUrl}\": ${errorMessage}`,\n });\n }\n\n return true;\n }\n\n return false;\n }\n}\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#method-getScriptSource */\nexport type DebuggerGetScriptSource = CdpMessage<\n 'Debugger.getScriptSource',\n Protocol.Debugger.GetScriptSourceRequest,\n Protocol.Debugger.GetScriptSourceResponse\n>;\n\nfunction respond<T extends CdpMessage>(\n socket: WS,\n request: DebuggerRequest<T>,\n response: DebuggerResponse<T>['result'] | { error: string }\n) {\n if ('error' in response) {\n socket.send(JSON.stringify({ id: request.id, error: { message: response.error } }));\n } else {\n socket.send(JSON.stringify({ id: request.id, result: response }));\n }\n\n return null;\n}\n\nfunction isUrl(pathOrUrl: string) {\n try {\n const url = new URL(pathOrUrl);\n return ['http', 'https'].some((protocol) => url.protocol.toLowerCase().startsWith(protocol));\n } catch {\n return false;\n }\n}\n"],"names":["DebuggerScriptSourceHandler","constructor","device","onDebuggerMessage","message","socket","method","scriptId","params","pathOrUrl","_scriptIdToSourcePathMapping","get","isUrl","fetch","then","response","ok","text","respond","error","status","scriptSource","relativePath","path","resolve","_projectRoot","fs","readFileSync","errorMessage","Error","String","request","send","JSON","stringify","id","result","url","URL","some","protocol","toLowerCase","startsWith"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
class NetworkResponseHandler {
|
|
6
|
+
/** All known responses, mapped by request id */ storage = new Map();
|
|
7
|
+
onDeviceMessage(message) {
|
|
8
|
+
if (message.method === "Expo(Network.receivedResponseBody)") {
|
|
9
|
+
const { requestId , ...requestInfo } = message.params;
|
|
10
|
+
this.storage.set(requestId, requestInfo);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
onDebuggerMessage(message, { socket }) {
|
|
16
|
+
if (message.method === "Network.getResponseBody" && this.storage.has(message.params.requestId)) {
|
|
17
|
+
const response = {
|
|
18
|
+
id: message.id,
|
|
19
|
+
result: this.storage.get(message.params.requestId)
|
|
20
|
+
};
|
|
21
|
+
socket.send(JSON.stringify(response));
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.NetworkResponseHandler = NetworkResponseHandler;
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=NetworkResponse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/NetworkResponse.ts"],"sourcesContent":["import type { Protocol } from 'devtools-protocol';\nimport type { DebuggerInfo } from 'metro-inspector-proxy';\n\nimport {\n CdpMessage,\n InspectorHandler,\n DeviceRequest,\n DebuggerRequest,\n DebuggerResponse,\n DeviceResponse,\n} from './types';\n\nexport class NetworkResponseHandler implements InspectorHandler {\n /** All known responses, mapped by request id */\n storage = new Map<string, DebuggerResponse<NetworkGetResponseBody>['result']>();\n\n onDeviceMessage(message: DeviceRequest<NetworkReceivedResponseBody>) {\n if (message.method === 'Expo(Network.receivedResponseBody)') {\n const { requestId, ...requestInfo } = message.params;\n this.storage.set(requestId, requestInfo);\n return true;\n }\n\n return false;\n }\n\n onDebuggerMessage(\n message: DebuggerRequest<NetworkGetResponseBody>,\n { socket }: Pick<DebuggerInfo, 'socket'>\n ) {\n if (\n message.method === 'Network.getResponseBody' &&\n this.storage.has(message.params.requestId)\n ) {\n const response: DeviceResponse<NetworkGetResponseBody> = {\n id: message.id,\n result: this.storage.get(message.params.requestId)!,\n };\n\n socket.send(JSON.stringify(response));\n return true;\n }\n\n return false;\n }\n}\n\n/** Custom message to transfer the response body data to the proxy */\nexport type NetworkReceivedResponseBody = CdpMessage<\n 'Expo(Network.receivedResponseBody)',\n Protocol.Network.GetResponseBodyRequest & Protocol.Network.GetResponseBodyResponse,\n never\n>;\n\n/** @see https://chromedevtools.github.io/devtools-protocol/1-2/Network/#method-getResponseBody */\nexport type NetworkGetResponseBody = CdpMessage<\n 'Network.getResponseBody',\n Protocol.Network.GetResponseBodyRequest,\n Protocol.Network.GetResponseBodyResponse\n>;\n"],"names":["NetworkResponseHandler","storage","Map","onDeviceMessage","message","method","requestId","requestInfo","params","set","onDebuggerMessage","socket","has","response","id","result","get","send","JSON","stringify"],"mappings":"AAAA;;;;AAYO,MAAMA,sBAAsB;IACjC,gDAAgD,CAChDC,OAAO,GAAG,IAAIC,GAAG,EAA8D,CAAC;IAEhFC,eAAe,CAACC,OAAmD,EAAE;QACnE,IAAIA,OAAO,CAACC,MAAM,KAAK,oCAAoC,EAAE;YAC3D,MAAM,EAAEC,SAAS,CAAA,EAAE,GAAGC,WAAW,EAAE,GAAGH,OAAO,CAACI,MAAM,AAAC;YACrD,IAAI,CAACP,OAAO,CAACQ,GAAG,CAACH,SAAS,EAAEC,WAAW,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC;SACb;QAED,OAAO,KAAK,CAAC;KACd;IAEDG,iBAAiB,CACfN,OAAgD,EAChD,EAAEO,MAAM,CAAA,EAAgC,EACxC;QACA,IACEP,OAAO,CAACC,MAAM,KAAK,yBAAyB,IAC5C,IAAI,CAACJ,OAAO,CAACW,GAAG,CAACR,OAAO,CAACI,MAAM,CAACF,SAAS,CAAC,EAC1C;YACA,MAAMO,QAAQ,GAA2C;gBACvDC,EAAE,EAAEV,OAAO,CAACU,EAAE;gBACdC,MAAM,EAAE,IAAI,CAACd,OAAO,CAACe,GAAG,CAACZ,OAAO,CAACI,MAAM,CAACF,SAAS,CAAC;aACnD,AAAC;YAEFK,MAAM,CAACM,IAAI,CAACC,IAAI,CAACC,SAAS,CAACN,QAAQ,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;SACb;QAED,OAAO,KAAK,CAAC;KACd;CACF;QAjCYb,sBAAsB,GAAtBA,sBAAsB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
class PageReloadHandler {
|
|
6
|
+
constructor(metroBundler){
|
|
7
|
+
this.metroBundler = metroBundler;
|
|
8
|
+
}
|
|
9
|
+
onDebuggerMessage(message, { socket }) {
|
|
10
|
+
if (message.method === "Page.reload") {
|
|
11
|
+
this.metroBundler.broadcastMessage("reload");
|
|
12
|
+
socket.send(JSON.stringify({
|
|
13
|
+
id: message.id
|
|
14
|
+
}));
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.PageReloadHandler = PageReloadHandler;
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=PageReload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/PageReload.ts"],"sourcesContent":["import type { Protocol } from 'devtools-protocol';\nimport { DebuggerInfo } from 'metro-inspector-proxy';\n\nimport { MetroBundlerDevServer } from '../../MetroBundlerDevServer';\nimport { CdpMessage, DebuggerRequest, InspectorHandler } from './types';\n\nexport class PageReloadHandler implements InspectorHandler {\n constructor(private readonly metroBundler: MetroBundlerDevServer) {}\n\n onDebuggerMessage(\n message: DebuggerRequest<PageReload>,\n { socket }: Pick<DebuggerInfo, 'socket'>\n ) {\n if (message.method === 'Page.reload') {\n this.metroBundler.broadcastMessage('reload');\n socket.send(JSON.stringify({ id: message.id }));\n return true;\n }\n\n return false;\n }\n}\n\n/** @see https://chromedevtools.github.io/devtools-protocol/1-2/Page/#method-reload */\nexport type PageReload = CdpMessage<'Page.reload', Protocol.Page.ReloadRequest, never>;\n"],"names":["PageReloadHandler","constructor","metroBundler","onDebuggerMessage","message","socket","method","broadcastMessage","send","JSON","stringify","id"],"mappings":"AAAA;;;;AAMO,MAAMA,iBAAiB;IAC5BC,YAA6BC,YAAmC,CAAE;aAArCA,YAAmC,GAAnCA,YAAmC;KAAI;IAEpEC,iBAAiB,CACfC,OAAoC,EACpC,EAAEC,MAAM,CAAA,EAAgC,EACxC;QACA,IAAID,OAAO,CAACE,MAAM,KAAK,aAAa,EAAE;YACpC,IAAI,CAACJ,YAAY,CAACK,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAC7CF,MAAM,CAACG,IAAI,CAACC,IAAI,CAACC,SAAS,CAAC;gBAAEC,EAAE,EAAEP,OAAO,CAACO,EAAE;aAAE,CAAC,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;SACb;QAED,OAAO,KAAK,CAAC;KACd;CACF;QAfYX,iBAAiB,GAAjBA,iBAAiB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
class VscodeCompatHandler {
|
|
6
|
+
/** Keep track of `Runtime.getProperties` responses to intercept, by request id */ interceptGetProperties = new Set();
|
|
7
|
+
onDebuggerMessage(message, { socket }) {
|
|
8
|
+
// Hermes doesn't seem to handle this request, but `locations` have to be returned.
|
|
9
|
+
// Respond with an empty location to make it "spec compliant" with Chrome DevTools.
|
|
10
|
+
if (message.method === "Debugger.getPossibleBreakpoints") {
|
|
11
|
+
const response = {
|
|
12
|
+
id: message.id,
|
|
13
|
+
result: {
|
|
14
|
+
locations: []
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
socket.send(JSON.stringify(response));
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
// Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.
|
|
21
|
+
// See: https://github.com/microsoft/vscode-js-debug/issues/1583
|
|
22
|
+
if (message.method === "Runtime.getProperties") {
|
|
23
|
+
this.interceptGetProperties.add(message.id);
|
|
24
|
+
}
|
|
25
|
+
// Hermes and vscode have trouble setting breakpoints by `urlRegex` through `Debugger.setBreakpointByUrl`.
|
|
26
|
+
// Vscode adds `file://` to a URL containing `http://`, which confuses Hermes and sets it to the wrong location.
|
|
27
|
+
// Hermes needs to create the breakpoint to get the proper ID, but it must be unbounded.
|
|
28
|
+
// Once the sourcemap is loaded, vscode will rebind the unbounded breakpoint to the correct location (using `Debugger.setBreakpoint`).
|
|
29
|
+
if (message.method === "Debugger.setBreakpointByUrl" && message.params.urlRegex) {
|
|
30
|
+
// Explicitly force the breakpoint to be unbounded
|
|
31
|
+
message.params.url = "file://__invalid_url__";
|
|
32
|
+
delete message.params.urlRegex;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
onDeviceMessage(message) {
|
|
37
|
+
// Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.
|
|
38
|
+
// See: https://github.com/microsoft/vscode-js-debug/issues/1583
|
|
39
|
+
if ("id" in message && this.interceptGetProperties.has(message.id)) {
|
|
40
|
+
this.interceptGetProperties.delete(message.id);
|
|
41
|
+
var _result;
|
|
42
|
+
for (const item of (_result = message.result.result) != null ? _result : []){
|
|
43
|
+
var ref;
|
|
44
|
+
// Force-fully format the properties description to be an empty string
|
|
45
|
+
// See: https://github.com/facebook/hermes/issues/114
|
|
46
|
+
if (item.value) {
|
|
47
|
+
var _description;
|
|
48
|
+
item.value.description = (_description = item.value.description) != null ? _description : "";
|
|
49
|
+
}
|
|
50
|
+
// Avoid passing the `objectId` for symbol types.
|
|
51
|
+
// When collapsing in vscode, it will fetch information about the symbol using the `objectId`.
|
|
52
|
+
// The `Runtime.getProperties` request of the symbol hard-crashes Hermes.
|
|
53
|
+
if (((ref = item.value) == null ? void 0 : ref.type) === "symbol" && item.value.objectId) {
|
|
54
|
+
delete item.value.objectId;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.VscodeCompatHandler = VscodeCompatHandler;
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=VscodeCompat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/VscodeCompat.ts"],"sourcesContent":["import type { Protocol } from 'devtools-protocol';\nimport type { DebuggerInfo } from 'metro-inspector-proxy';\n\nimport { CdpMessage, DebuggerRequest, DeviceResponse, InspectorHandler } from './types';\n\nexport class VscodeCompatHandler implements InspectorHandler {\n /** Keep track of `Runtime.getProperties` responses to intercept, by request id */\n interceptGetProperties = new Set<number>();\n\n onDebuggerMessage(\n message:\n | DebuggerRequest<DebuggerGetPossibleBreakpoints>\n | DebuggerRequest<DebuggerSetBreakpointByUrl>\n | DebuggerRequest<RuntimeGetProperties>,\n { socket }: Pick<DebuggerInfo, 'socket'>\n ) {\n // Hermes doesn't seem to handle this request, but `locations` have to be returned.\n // Respond with an empty location to make it \"spec compliant\" with Chrome DevTools.\n if (message.method === 'Debugger.getPossibleBreakpoints') {\n const response: DeviceResponse<DebuggerGetPossibleBreakpoints> = {\n id: message.id,\n result: { locations: [] },\n };\n socket.send(JSON.stringify(response));\n return true;\n }\n\n // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.\n // See: https://github.com/microsoft/vscode-js-debug/issues/1583\n if (message.method === 'Runtime.getProperties') {\n this.interceptGetProperties.add(message.id);\n }\n\n // Hermes and vscode have trouble setting breakpoints by `urlRegex` through `Debugger.setBreakpointByUrl`.\n // Vscode adds `file://` to a URL containing `http://`, which confuses Hermes and sets it to the wrong location.\n // Hermes needs to create the breakpoint to get the proper ID, but it must be unbounded.\n // Once the sourcemap is loaded, vscode will rebind the unbounded breakpoint to the correct location (using `Debugger.setBreakpoint`).\n if (message.method === 'Debugger.setBreakpointByUrl' && message.params.urlRegex) {\n // Explicitly force the breakpoint to be unbounded\n message.params.url = 'file://__invalid_url__';\n delete message.params.urlRegex;\n }\n\n return false;\n }\n\n onDeviceMessage(message: DeviceResponse<RuntimeGetProperties>) {\n // Vscode doesn't seem to work nicely with missing `description` fields on `RemoteObject` instances.\n // See: https://github.com/microsoft/vscode-js-debug/issues/1583\n if ('id' in message && this.interceptGetProperties.has(message.id)) {\n this.interceptGetProperties.delete(message.id);\n\n for (const item of message.result.result ?? []) {\n // Force-fully format the properties description to be an empty string\n // See: https://github.com/facebook/hermes/issues/114\n if (item.value) {\n item.value.description = item.value.description ?? '';\n }\n\n // Avoid passing the `objectId` for symbol types.\n // When collapsing in vscode, it will fetch information about the symbol using the `objectId`.\n // The `Runtime.getProperties` request of the symbol hard-crashes Hermes.\n if (item.value?.type === 'symbol' && item.value.objectId) {\n delete item.value.objectId;\n }\n }\n }\n\n return false;\n }\n}\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#method-getPossibleBreakpoints */\nexport type DebuggerGetPossibleBreakpoints = CdpMessage<\n 'Debugger.getPossibleBreakpoints',\n Protocol.Debugger.GetPossibleBreakpointsRequest,\n Protocol.Debugger.GetPossibleBreakpointsResponse\n>;\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#method-setBreakpointByUrl */\nexport type DebuggerSetBreakpointByUrl = CdpMessage<\n 'Debugger.setBreakpointByUrl',\n Protocol.Debugger.SetBreakpointByUrlRequest,\n Protocol.Debugger.SetBreakpointByUrlResponse\n>;\n\n/** @see https://chromedevtools.github.io/devtools-protocol/v8/Runtime/#method-getProperties */\nexport type RuntimeGetProperties = CdpMessage<\n 'Runtime.getProperties',\n Protocol.Runtime.GetPropertiesRequest,\n Protocol.Runtime.GetPropertiesResponse\n>;\n"],"names":["VscodeCompatHandler","interceptGetProperties","Set","onDebuggerMessage","message","socket","method","response","id","result","locations","send","JSON","stringify","add","params","urlRegex","url","onDeviceMessage","has","delete","item","value","description","type","objectId"],"mappings":"AAAA;;;;AAKO,MAAMA,mBAAmB;IAC9B,kFAAkF,CAClFC,sBAAsB,GAAG,IAAIC,GAAG,EAAU,CAAC;IAE3CC,iBAAiB,CACfC,OAGyC,EACzC,EAAEC,MAAM,CAAA,EAAgC,EACxC;QACA,mFAAmF;QACnF,mFAAmF;QACnF,IAAID,OAAO,CAACE,MAAM,KAAK,iCAAiC,EAAE;YACxD,MAAMC,QAAQ,GAAmD;gBAC/DC,EAAE,EAAEJ,OAAO,CAACI,EAAE;gBACdC,MAAM,EAAE;oBAAEC,SAAS,EAAE,EAAE;iBAAE;aAC1B,AAAC;YACFL,MAAM,CAACM,IAAI,CAACC,IAAI,CAACC,SAAS,CAACN,QAAQ,CAAC,CAAC,CAAC;YACtC,OAAO,IAAI,CAAC;SACb;QAED,oGAAoG;QACpG,gEAAgE;QAChE,IAAIH,OAAO,CAACE,MAAM,KAAK,uBAAuB,EAAE;YAC9C,IAAI,CAACL,sBAAsB,CAACa,GAAG,CAACV,OAAO,CAACI,EAAE,CAAC,CAAC;SAC7C;QAED,0GAA0G;QAC1G,gHAAgH;QAChH,wFAAwF;QACxF,sIAAsI;QACtI,IAAIJ,OAAO,CAACE,MAAM,KAAK,6BAA6B,IAAIF,OAAO,CAACW,MAAM,CAACC,QAAQ,EAAE;YAC/E,kDAAkD;YAClDZ,OAAO,CAACW,MAAM,CAACE,GAAG,GAAG,wBAAwB,CAAC;YAC9C,OAAOb,OAAO,CAACW,MAAM,CAACC,QAAQ,CAAC;SAChC;QAED,OAAO,KAAK,CAAC;KACd;IAEDE,eAAe,CAACd,OAA6C,EAAE;QAC7D,oGAAoG;QACpG,gEAAgE;QAChE,IAAI,IAAI,IAAIA,OAAO,IAAI,IAAI,CAACH,sBAAsB,CAACkB,GAAG,CAACf,OAAO,CAACI,EAAE,CAAC,EAAE;YAClE,IAAI,CAACP,sBAAsB,CAACmB,MAAM,CAAChB,OAAO,CAACI,EAAE,CAAC,CAAC;gBAE5BJ,OAAqB;YAAxC,KAAK,MAAMiB,IAAI,IAAIjB,CAAAA,OAAqB,GAArBA,OAAO,CAACK,MAAM,CAACA,MAAM,YAArBL,OAAqB,GAAI,EAAE,CAAE;oBAU1CiB,GAAU;gBATd,sEAAsE;gBACtE,qDAAqD;gBACrD,IAAIA,IAAI,CAACC,KAAK,EAAE;wBACWD,YAAsB;oBAA/CA,IAAI,CAACC,KAAK,CAACC,WAAW,GAAGF,CAAAA,YAAsB,GAAtBA,IAAI,CAACC,KAAK,CAACC,WAAW,YAAtBF,YAAsB,GAAI,EAAE,CAAC;iBACvD;gBAED,iDAAiD;gBACjD,8FAA8F;gBAC9F,yEAAyE;gBACzE,IAAIA,CAAAA,CAAAA,GAAU,GAAVA,IAAI,CAACC,KAAK,SAAM,GAAhBD,KAAAA,CAAgB,GAAhBA,GAAU,CAAEG,IAAI,CAAA,KAAK,QAAQ,IAAIH,IAAI,CAACC,KAAK,CAACG,QAAQ,EAAE;oBACxD,OAAOJ,IAAI,CAACC,KAAK,CAACG,QAAQ,CAAC;iBAC5B;aACF;SACF;QAED,OAAO,KAAK,CAAC;KACd;CACF;QAjEYzB,mBAAmB,GAAnBA,mBAAmB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/start/server/metro/inspector-proxy/handlers/types.ts"],"sourcesContent":["import { DebuggerInfo } from 'metro-inspector-proxy';\n\nexport interface InspectorHandler {\n /**\n * Intercept a message coming from the device, modify or respond to it through `this._sendMessageToDevice`.\n * Return `true` if the message was handled, this will stop the message propagation.\n */\n onDeviceMessage?(message: DeviceRequest | DeviceResponse, info: DebuggerInfo): boolean;\n\n /**\n * Intercept a message coming from the debugger, modify or respond to it through `socket.send`.\n * Return `true` if the message was handled, this will stop the message propagation.\n */\n onDebuggerMessage?(message: DebuggerRequest, info: DebuggerInfo): boolean;\n}\n\n/**\n * The outline of a basic Chrome DevTools Protocol request, either from device or debugger.\n * Both the request and response parameters could be optional, use `never` to enforce these fields.\n */\nexport type CdpMessage<\n Method extends string = string,\n Request extends object = object,\n Response extends object = object\n> = {\n id: number;\n method: Method;\n params: Request;\n result: Response;\n};\n\nexport type DeviceRequest<M extends CdpMessage = CdpMessage> = Pick<M, 'method' | 'params'>;\nexport type DeviceResponse<M extends CdpMessage = CdpMessage> = Pick<M, 'id' | 'result'>;\n\nexport type DebuggerRequest<M extends CdpMessage = CdpMessage> = Pick<\n M,\n 'id' | 'method' | 'params'\n>;\nexport type DebuggerResponse<M extends CdpMessage = CdpMessage> = Pick<M, 'result'>;\n"],"names":[],"mappings":"AAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ExpoInspectorProxy", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return _proxy.ExpoInspectorProxy;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
exports.createInspectorProxy = createInspectorProxy;
|
|
12
|
+
var _log = require("../../../../log");
|
|
13
|
+
var _resolveFromProject = require("../resolveFromProject");
|
|
14
|
+
var _device = require("./device");
|
|
15
|
+
var _proxy = require("./proxy");
|
|
16
|
+
function createInspectorProxy(metroBundler, projectRoot) {
|
|
17
|
+
_log.Log.warn("Experimental inspector proxy enabled. This early version requires newer Metro functionality, which is only available in SDK 49+.");
|
|
18
|
+
// Import the installed `metro-inspector-proxy` from the project
|
|
19
|
+
// We use these base classes to extend functionality
|
|
20
|
+
const { InspectorProxy: MetroInspectorProxy } = (0, _resolveFromProject).importMetroInspectorProxyFromProject(projectRoot);
|
|
21
|
+
// The device is slightly more complicated, we need to extend that class
|
|
22
|
+
const ExpoInspectorDevice = (0, _device).createInspectorDeviceClass(metroBundler, (0, _resolveFromProject).importMetroInspectorDeviceFromProject(projectRoot));
|
|
23
|
+
const inspectorProxy = new _proxy.ExpoInspectorProxy(new MetroInspectorProxy(projectRoot), ExpoInspectorDevice);
|
|
24
|
+
return inspectorProxy;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/metro/inspector-proxy/index.ts"],"sourcesContent":["import { Log } from '../../../../log';\nimport { MetroBundlerDevServer } from '../MetroBundlerDevServer';\nimport {\n importMetroInspectorDeviceFromProject,\n importMetroInspectorProxyFromProject,\n} from '../resolveFromProject';\nimport { createInspectorDeviceClass } from './device';\nimport { ExpoInspectorProxy } from './proxy';\n\nexport { ExpoInspectorProxy } from './proxy';\n\nexport function createInspectorProxy(metroBundler: MetroBundlerDevServer, projectRoot: string) {\n Log.warn(\n 'Experimental inspector proxy enabled. This early version requires newer Metro functionality, which is only available in SDK 49+.'\n );\n\n // Import the installed `metro-inspector-proxy` from the project\n // We use these base classes to extend functionality\n const { InspectorProxy: MetroInspectorProxy } = importMetroInspectorProxyFromProject(projectRoot);\n // The device is slightly more complicated, we need to extend that class\n const ExpoInspectorDevice = createInspectorDeviceClass(\n metroBundler,\n importMetroInspectorDeviceFromProject(projectRoot)\n );\n\n const inspectorProxy = new ExpoInspectorProxy(\n new MetroInspectorProxy(projectRoot),\n ExpoInspectorDevice\n );\n\n return inspectorProxy;\n}\n"],"names":["ExpoInspectorProxy","createInspectorProxy","metroBundler","projectRoot","Log","warn","InspectorProxy","MetroInspectorProxy","importMetroInspectorProxyFromProject","ExpoInspectorDevice","createInspectorDeviceClass","importMetroInspectorDeviceFromProject","inspectorProxy"],"mappings":"AAAA;;;;+BASSA,oBAAkB;;;eAFQ,MAAS,CAEnCA,kBAAkB;;;QAEXC,oBAAoB,GAApBA,oBAAoB;AAXhB,IAAA,IAAiB,WAAjB,iBAAiB,CAAA;AAK9B,IAAA,mBAAuB,WAAvB,uBAAuB,CAAA;AACa,IAAA,OAAU,WAAV,UAAU,CAAA;AAClB,IAAA,MAAS,WAAT,SAAS,CAAA;AAIrC,SAASA,oBAAoB,CAACC,YAAmC,EAAEC,WAAmB,EAAE;IAC7FC,IAAG,IAAA,CAACC,IAAI,CACN,kIAAkI,CACnI,CAAC;IAEF,gEAAgE;IAChE,oDAAoD;IACpD,MAAM,EAAEC,cAAc,EAAEC,mBAAmB,CAAA,EAAE,GAAGC,CAAAA,GAAAA,mBAAoC,AAAa,CAAA,qCAAb,CAACL,WAAW,CAAC,AAAC;IAClG,wEAAwE;IACxE,MAAMM,mBAAmB,GAAGC,CAAAA,GAAAA,OAA0B,AAGrD,CAAA,2BAHqD,CACpDR,YAAY,EACZS,CAAAA,GAAAA,mBAAqC,AAAa,CAAA,sCAAb,CAACR,WAAW,CAAC,CACnD,AAAC;IAEF,MAAMS,cAAc,GAAG,IAAIZ,MAAkB,mBAAA,CAC3C,IAAIO,mBAAmB,CAACJ,WAAW,CAAC,EACpCM,mBAAmB,CACpB,AAAC;IAEF,OAAOG,cAAc,CAAC;CACvB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
var _url = require("url");
|
|
6
|
+
var _ws = _interopRequireDefault(require("ws"));
|
|
7
|
+
var _log = require("../../../../log");
|
|
8
|
+
function _interopRequireDefault(obj) {
|
|
9
|
+
return obj && obj.__esModule ? obj : {
|
|
10
|
+
default: obj
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const WS_DEVICE_URL = "/inspector/device";
|
|
14
|
+
const WS_DEBUGGER_URL = "/inspector/debug";
|
|
15
|
+
const WS_GENERIC_ERROR_STATUS = 1011;
|
|
16
|
+
const debug = require("debug")("expo:metro:inspector-proxy:proxy");
|
|
17
|
+
class ExpoInspectorProxy {
|
|
18
|
+
constructor(metroProxy, DeviceClass, devices = new Map()){
|
|
19
|
+
this.metroProxy = metroProxy;
|
|
20
|
+
this.DeviceClass = DeviceClass;
|
|
21
|
+
this.devices = devices;
|
|
22
|
+
// monkey-patch the device list to expose it within the metro inspector
|
|
23
|
+
this.metroProxy._devices = this.devices;
|
|
24
|
+
// force httpEndpointMiddleware to be bound to this proxy instance
|
|
25
|
+
this.processRequest = this.processRequest.bind(this);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Initialize the server address from the metro server.
|
|
29
|
+
* This is required to properly reference sourcemaps for the debugger.
|
|
30
|
+
*/ setServerAddress(server) {
|
|
31
|
+
const addressInfo = server.address();
|
|
32
|
+
if (typeof addressInfo === "string") {
|
|
33
|
+
throw new Error(`Inspector proxy could not resolve the server address, got "${addressInfo}"`);
|
|
34
|
+
} else if (addressInfo === null) {
|
|
35
|
+
throw new Error(`Inspector proxy could not resolve the server address, got "null"`);
|
|
36
|
+
}
|
|
37
|
+
const { address , port , family } = addressInfo;
|
|
38
|
+
if (family === "IPv6") {
|
|
39
|
+
this.metroProxy._serverAddressWithPort = `[${address != null ? address : "::1"}]:${port}`;
|
|
40
|
+
} else {
|
|
41
|
+
this.metroProxy._serverAddressWithPort = `${address != null ? address : "localhost"}:${port}`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** @see https://chromedevtools.github.io/devtools-protocol/#endpoints */ processRequest(req, res, next) {
|
|
45
|
+
this.metroProxy.processRequest(req, res, next);
|
|
46
|
+
}
|
|
47
|
+
createWebSocketListeners(server) {
|
|
48
|
+
if (server) {
|
|
49
|
+
this.setServerAddress(server);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
[WS_DEVICE_URL]: this.createDeviceWebSocketServer(),
|
|
53
|
+
[WS_DEBUGGER_URL]: this.createDebuggerWebSocketServer()
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
createDeviceWebSocketServer() {
|
|
57
|
+
const wss = new _ws.default.Server({
|
|
58
|
+
noServer: true,
|
|
59
|
+
perMessageDeflate: false
|
|
60
|
+
});
|
|
61
|
+
// See: https://github.com/facebook/metro/blob/eeb211fdcfdcb9e7f8a51721bd0f48bc7d0d211f/packages/metro-inspector-proxy/src/InspectorProxy.js#L157
|
|
62
|
+
wss.on("connection", (socket, request)=>{
|
|
63
|
+
try {
|
|
64
|
+
const deviceId = this.metroProxy._deviceCounter++;
|
|
65
|
+
const { deviceName , appName } = getNewDeviceInfo(request.url);
|
|
66
|
+
this.devices.set(deviceId, new this.DeviceClass(deviceId, deviceName, appName, socket, this.metroProxy._projectRoot));
|
|
67
|
+
debug("New device connected: device=%s, app=%s", deviceName, appName);
|
|
68
|
+
socket.on("close", ()=>{
|
|
69
|
+
this.devices.delete(deviceId);
|
|
70
|
+
debug("Device disconnected: device=%s, app=%s", deviceName, appName);
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
let message = "";
|
|
74
|
+
debug("Could not establish a connection to on-device debugger:", error);
|
|
75
|
+
if (error instanceof Error) {
|
|
76
|
+
message = error.toString();
|
|
77
|
+
_log.Log.error("Failed to create a socket connection to on-device debugger (Hermes engine).");
|
|
78
|
+
_log.Log.exception(error);
|
|
79
|
+
} else {
|
|
80
|
+
_log.Log.error("Failed to create a socket connection to on-device debugger (Hermes engine), unknown error.");
|
|
81
|
+
}
|
|
82
|
+
socket.close(WS_GENERIC_ERROR_STATUS, message || "Unknown error");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return wss;
|
|
86
|
+
}
|
|
87
|
+
createDebuggerWebSocketServer() {
|
|
88
|
+
const wss = new _ws.default.Server({
|
|
89
|
+
noServer: true,
|
|
90
|
+
perMessageDeflate: false
|
|
91
|
+
});
|
|
92
|
+
// See: https://github.com/facebook/metro/blob/eeb211fdcfdcb9e7f8a51721bd0f48bc7d0d211f/packages/metro-inspector-proxy/src/InspectorProxy.js#L193
|
|
93
|
+
wss.on("connection", (socket, request)=>{
|
|
94
|
+
try {
|
|
95
|
+
const { deviceId , pageId } = getExistingDeviceInfo(request.url);
|
|
96
|
+
if (!deviceId || !pageId) {
|
|
97
|
+
// TODO(cedric): change these errors to proper error types
|
|
98
|
+
throw new Error(`Missing "device" and/or "page" IDs in query parameters`);
|
|
99
|
+
}
|
|
100
|
+
const device = this.devices.get(parseInt(deviceId, 10));
|
|
101
|
+
if (!device) {
|
|
102
|
+
// TODO(cedric): change these errors to proper error types
|
|
103
|
+
throw new Error(`Device with ID "${deviceId}" not found.`);
|
|
104
|
+
}
|
|
105
|
+
debug("New debugger connected: device=%s, app=%s", device._name, device._app);
|
|
106
|
+
device.handleDebuggerConnection(socket, pageId);
|
|
107
|
+
socket.on("close", ()=>{
|
|
108
|
+
debug("Debugger disconnected: device=%s, app=%s", device._name, device._app);
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
let message = "";
|
|
112
|
+
debug("Could not establish a connection to debugger:", error);
|
|
113
|
+
if (error instanceof Error) {
|
|
114
|
+
message = error.toString();
|
|
115
|
+
_log.Log.error("Failed to create a socket connection to the debugger.");
|
|
116
|
+
_log.Log.exception(error);
|
|
117
|
+
} else {
|
|
118
|
+
_log.Log.error("Failed to create a socket connection to the debugger, unkown error.");
|
|
119
|
+
}
|
|
120
|
+
socket.close(WS_GENERIC_ERROR_STATUS, message || "Unknown error");
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return wss;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.ExpoInspectorProxy = ExpoInspectorProxy;
|
|
127
|
+
function asString(value = "") {
|
|
128
|
+
return Array.isArray(value) ? value.join() : value;
|
|
129
|
+
}
|
|
130
|
+
function getNewDeviceInfo(url) {
|
|
131
|
+
const { query } = (0, _url).parse(url != null ? url : "", true);
|
|
132
|
+
return {
|
|
133
|
+
deviceName: asString(query.name) || "Unknown device name",
|
|
134
|
+
appName: asString(query.app) || "Unknown app name"
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function getExistingDeviceInfo(url) {
|
|
138
|
+
const { query } = (0, _url).parse(url != null ? url : "", true);
|
|
139
|
+
return {
|
|
140
|
+
deviceId: asString(query.device),
|
|
141
|
+
pageId: asString(query.page)
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/start/server/metro/inspector-proxy/proxy.ts"],"sourcesContent":["import type { Server as HttpServer, IncomingMessage, ServerResponse } from 'http';\nimport type { Server as HttpsServer } from 'https';\nimport type { InspectorProxy as MetroProxy, Device as MetroDevice } from 'metro-inspector-proxy';\nimport { parse } from 'url';\nimport WS, { Server as WSServer } from 'ws';\n\nimport { Log } from '../../../../log';\n\nconst WS_DEVICE_URL = '/inspector/device';\nconst WS_DEBUGGER_URL = '/inspector/debug';\nconst WS_GENERIC_ERROR_STATUS = 1011;\n\nconst debug = require('debug')('expo:metro:inspector-proxy:proxy') as typeof console.log;\n\n// This is a workaround for `ConstructorType` not working on dynamically generated classes\ntype Instantiatable<Instance> = new (...args: any) => Instance;\n\nexport class ExpoInspectorProxy<D extends MetroDevice = MetroDevice> {\n constructor(\n public readonly metroProxy: MetroProxy,\n private DeviceClass: Instantiatable<D>,\n public readonly devices: Map<number, D> = new Map()\n ) {\n // monkey-patch the device list to expose it within the metro inspector\n this.metroProxy._devices = this.devices;\n\n // force httpEndpointMiddleware to be bound to this proxy instance\n this.processRequest = this.processRequest.bind(this);\n }\n\n /**\n * Initialize the server address from the metro server.\n * This is required to properly reference sourcemaps for the debugger.\n */\n public setServerAddress(server: HttpServer | HttpsServer) {\n const addressInfo = server.address();\n\n if (typeof addressInfo === 'string') {\n throw new Error(`Inspector proxy could not resolve the server address, got \"${addressInfo}\"`);\n } else if (addressInfo === null) {\n throw new Error(`Inspector proxy could not resolve the server address, got \"null\"`);\n }\n\n const { address, port, family } = addressInfo;\n\n if (family === 'IPv6') {\n this.metroProxy._serverAddressWithPort = `[${address ?? '::1'}]:${port}`;\n } else {\n this.metroProxy._serverAddressWithPort = `${address ?? 'localhost'}:${port}`;\n }\n }\n\n /** @see https://chromedevtools.github.io/devtools-protocol/#endpoints */\n public processRequest(req: IncomingMessage, res: ServerResponse, next: (error?: Error) => any) {\n this.metroProxy.processRequest(req, res, next);\n }\n\n public createWebSocketListeners(server?: HttpServer | HttpsServer): Record<string, WSServer> {\n if (server) {\n this.setServerAddress(server);\n }\n\n return {\n [WS_DEVICE_URL]: this.createDeviceWebSocketServer(),\n [WS_DEBUGGER_URL]: this.createDebuggerWebSocketServer(),\n };\n }\n\n private createDeviceWebSocketServer() {\n const wss = new WS.Server({\n noServer: true,\n perMessageDeflate: false,\n });\n\n // See: https://github.com/facebook/metro/blob/eeb211fdcfdcb9e7f8a51721bd0f48bc7d0d211f/packages/metro-inspector-proxy/src/InspectorProxy.js#L157\n wss.on('connection', (socket, request) => {\n try {\n const deviceId = this.metroProxy._deviceCounter++;\n const { deviceName, appName } = getNewDeviceInfo(request.url);\n\n this.devices.set(\n deviceId,\n new this.DeviceClass(deviceId, deviceName, appName, socket, this.metroProxy._projectRoot)\n );\n\n debug('New device connected: device=%s, app=%s', deviceName, appName);\n\n socket.on('close', () => {\n this.devices.delete(deviceId);\n debug('Device disconnected: device=%s, app=%s', deviceName, appName);\n });\n } catch (error: unknown) {\n let message = '';\n\n debug('Could not establish a connection to on-device debugger:', error);\n\n if (error instanceof Error) {\n message = error.toString();\n Log.error('Failed to create a socket connection to on-device debugger (Hermes engine).');\n Log.exception(error);\n } else {\n Log.error(\n 'Failed to create a socket connection to on-device debugger (Hermes engine), unknown error.'\n );\n }\n\n socket.close(WS_GENERIC_ERROR_STATUS, message || 'Unknown error');\n }\n });\n\n return wss;\n }\n\n private createDebuggerWebSocketServer() {\n const wss = new WS.Server({\n noServer: true,\n perMessageDeflate: false,\n });\n\n // See: https://github.com/facebook/metro/blob/eeb211fdcfdcb9e7f8a51721bd0f48bc7d0d211f/packages/metro-inspector-proxy/src/InspectorProxy.js#L193\n wss.on('connection', (socket, request) => {\n try {\n const { deviceId, pageId } = getExistingDeviceInfo(request.url);\n if (!deviceId || !pageId) {\n // TODO(cedric): change these errors to proper error types\n throw new Error(`Missing \"device\" and/or \"page\" IDs in query parameters`);\n }\n\n const device = this.devices.get(parseInt(deviceId, 10));\n if (!device) {\n // TODO(cedric): change these errors to proper error types\n throw new Error(`Device with ID \"${deviceId}\" not found.`);\n }\n\n debug('New debugger connected: device=%s, app=%s', device._name, device._app);\n\n device.handleDebuggerConnection(socket, pageId);\n\n socket.on('close', () => {\n debug('Debugger disconnected: device=%s, app=%s', device._name, device._app);\n });\n } catch (error: unknown) {\n let message = '';\n\n debug('Could not establish a connection to debugger:', error);\n\n if (error instanceof Error) {\n message = error.toString();\n Log.error('Failed to create a socket connection to the debugger.');\n Log.exception(error);\n } else {\n Log.error('Failed to create a socket connection to the debugger, unkown error.');\n }\n\n socket.close(WS_GENERIC_ERROR_STATUS, message || 'Unknown error');\n }\n });\n\n return wss;\n }\n}\n\nfunction asString(value: string | string[] = ''): string {\n return Array.isArray(value) ? value.join() : value;\n}\n\nfunction getNewDeviceInfo(url: IncomingMessage['url']) {\n const { query } = parse(url ?? '', true);\n return {\n deviceName: asString(query.name) || 'Unknown device name',\n appName: asString(query.app) || 'Unknown app name',\n };\n}\n\nfunction getExistingDeviceInfo(url: IncomingMessage['url']) {\n const { query } = parse(url ?? '', true);\n return {\n deviceId: asString(query.device),\n pageId: asString(query.page),\n };\n}\n"],"names":["WS_DEVICE_URL","WS_DEBUGGER_URL","WS_GENERIC_ERROR_STATUS","debug","require","ExpoInspectorProxy","constructor","metroProxy","DeviceClass","devices","Map","_devices","processRequest","bind","setServerAddress","server","addressInfo","address","Error","port","family","_serverAddressWithPort","req","res","next","createWebSocketListeners","createDeviceWebSocketServer","createDebuggerWebSocketServer","wss","WS","Server","noServer","perMessageDeflate","on","socket","request","deviceId","_deviceCounter","deviceName","appName","getNewDeviceInfo","url","set","_projectRoot","delete","error","message","toString","Log","exception","close","pageId","getExistingDeviceInfo","device","get","parseInt","_name","_app","handleDebuggerConnection","asString","value","Array","isArray","join","query","parse","name","app","page"],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ var _env = require("../../../utils/env");
|
|
|
15
15
|
var _createDevServerMiddleware = require("../middleware/createDevServerMiddleware");
|
|
16
16
|
var _platformBundlers = require("../platformBundlers");
|
|
17
17
|
var _metroTerminalReporter = require("./MetroTerminalReporter");
|
|
18
|
+
var _inspectorProxy = require("./inspector-proxy");
|
|
18
19
|
var _resolveFromProject = require("./resolveFromProject");
|
|
19
20
|
var _withMetroMultiPlatform = require("./withMetroMultiPlatform");
|
|
20
21
|
function _interopRequireDefault(obj) {
|
|
@@ -22,7 +23,8 @@ function _interopRequireDefault(obj) {
|
|
|
22
23
|
default: obj
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
|
-
async function instantiateMetroAsync(
|
|
26
|
+
async function instantiateMetroAsync(metroBundler, options) {
|
|
27
|
+
const projectRoot = metroBundler.projectRoot;
|
|
26
28
|
let reportEvent;
|
|
27
29
|
const Metro = (0, _resolveFromProject).importMetroFromProject(projectRoot);
|
|
28
30
|
const ExpoMetroConfig = (0, _resolveFromProject).importExpoMetroConfigFromProject(projectRoot);
|
|
@@ -61,13 +63,27 @@ async function instantiateMetroAsync(projectRoot, options) {
|
|
|
61
63
|
}
|
|
62
64
|
return middleware.use(metroMiddleware);
|
|
63
65
|
};
|
|
66
|
+
// Create the custom inspector proxy only when enabled and opt-in
|
|
67
|
+
const inspectorProxy = metroConfig.server.runInspectorProxy && _env.env.EXPO_USE_CUSTOM_INSPECTOR_PROXY ? (0, _inspectorProxy).createInspectorProxy(metroBundler, metroBundler.projectRoot) : null;
|
|
68
|
+
if (inspectorProxy) {
|
|
69
|
+
// @ts-expect-error Property is read-only, but we need to disable it
|
|
70
|
+
metroConfig.server.runInspectorProxy = false;
|
|
71
|
+
}
|
|
64
72
|
middleware.use((0, _metroDebuggerMiddleware).createDebuggerTelemetryMiddleware(projectRoot, exp));
|
|
65
73
|
const server1 = await Metro.runServer(metroConfig, {
|
|
66
74
|
hmrEnabled: true,
|
|
67
|
-
websocketEndpoints
|
|
75
|
+
websocketEndpoints: {
|
|
76
|
+
...websocketEndpoints,
|
|
77
|
+
...inspectorProxy ? inspectorProxy.createWebSocketListeners() : {}
|
|
78
|
+
},
|
|
68
79
|
// @ts-expect-error Property was added in 0.73.4, remove this statement when updating Metro
|
|
69
80
|
watch: isWatchEnabled()
|
|
70
81
|
});
|
|
82
|
+
// Hook the inspector proxy in the Metro server
|
|
83
|
+
if (inspectorProxy) {
|
|
84
|
+
inspectorProxy.setServerAddress(server1);
|
|
85
|
+
middleware.use(inspectorProxy.processRequest);
|
|
86
|
+
}
|
|
71
87
|
if (attachToServer) {
|
|
72
88
|
// Expo SDK 44 and lower
|
|
73
89
|
const { messageSocket , eventsSocket } = attachToServer(server1);
|