metro-inspector-proxy
Advanced tools
Comparing version 0.75.0 to 0.75.1
{ | ||
"name": "metro-inspector-proxy", | ||
"version": "0.75.0", | ||
"version": "0.75.1", | ||
"description": "🚇 Inspector proxy for React Native and dev tools integration.", | ||
@@ -23,3 +23,4 @@ "main": "src/index.js", | ||
"ws": "^7.5.1", | ||
"yargs": "^17.5.1" | ||
"yargs": "^17.5.1", | ||
"node-fetch": "^2.2.0" | ||
}, | ||
@@ -26,0 +27,0 @@ "engines": { |
"use strict"; | ||
var fs = _interopRequireWildcard(require("fs")); | ||
var http = _interopRequireWildcard(require("http")); | ||
var path = _interopRequireWildcard(require("path")); | ||
var _nodeFetch = _interopRequireDefault(require("node-fetch")); | ||
var _ws = _interopRequireDefault(require("ws")); | ||
@@ -283,6 +283,10 @@ function _interopRequireDefault(obj) { | ||
// Wrapping just to make flow happy :) | ||
this._processMessageFromDevice(parsedPayload, this._debuggerConnection); | ||
this._processMessageFromDevice( | ||
parsedPayload, | ||
this._debuggerConnection | ||
).then(() => { | ||
const messageToSend = JSON.stringify(parsedPayload); | ||
debuggerSocket.send(messageToSend); | ||
}); | ||
} | ||
const messageToSend = JSON.stringify(parsedPayload); | ||
debuggerSocket.send(messageToSend); | ||
} | ||
@@ -375,3 +379,3 @@ } | ||
// Allows to make changes in incoming message from device. | ||
_processMessageFromDevice(payload, debuggerInfo) { | ||
async _processMessageFromDevice(payload, debuggerInfo) { | ||
// Replace Android addresses for scriptParsed event. | ||
@@ -391,2 +395,20 @@ if (payload.method === "Debugger.scriptParsed") { | ||
} | ||
const sourceMapURL = this._tryParseHTTPURL(params.sourceMapURL); | ||
if (sourceMapURL) { | ||
// Some debug clients do not support fetching HTTP URLs. If the | ||
// message headed to the debug client identifies the source map with | ||
// an HTTP URL, fetch the content here and convert the content to a | ||
// Data URL (which is more widely supported) before passing the | ||
// message to the debug client. | ||
try { | ||
const sourceMap = await this._fetchText(sourceMapURL); | ||
payload.params.sourceMapURL = | ||
"data:application/json;charset=utf-8;base64," + | ||
new Buffer(sourceMap).toString("base64"); | ||
} catch (exception) { | ||
this._sendErrorToDebugger( | ||
`Failed to fetch source map ${params.sourceMapURL}: ${exception.message}` | ||
); | ||
} | ||
} | ||
} | ||
@@ -416,13 +438,2 @@ if ("url" in params) { | ||
} | ||
if (debuggerInfo.pageId == REACT_NATIVE_RELOADABLE_PAGE_ID) { | ||
// Chrome won't use the source map unless it appears to be new. | ||
if (payload.params.sourceMapURL) { | ||
payload.params.sourceMapURL += | ||
"&cachePrevention=" + this._mapToDevicePageId(debuggerInfo.pageId); | ||
} | ||
if (payload.params.url) { | ||
payload.params.url += | ||
"&cachePrevention=" + this._mapToDevicePageId(debuggerInfo.pageId); | ||
} | ||
} | ||
} | ||
@@ -503,4 +514,3 @@ if ( | ||
_processDebuggerGetScriptSource(req, socket) { | ||
let scriptSource = `Source for script with id '${req.params.scriptId}' was not found.`; | ||
const sendResponse = () => { | ||
const sendSuccessResponse = (scriptSource) => { | ||
const result = { | ||
@@ -516,2 +526,19 @@ scriptSource, | ||
}; | ||
const sendErrorResponse = (error) => { | ||
// Tell the client that the request failed | ||
const result = { | ||
error: { | ||
message: error, | ||
}, | ||
}; | ||
socket.send( | ||
JSON.stringify({ | ||
id: req.id, | ||
result, | ||
}) | ||
); | ||
// Send to the console as well, so the user can see it | ||
this._sendErrorToDebugger(error); | ||
}; | ||
const pathToSource = this._scriptIdToSourcePathMapping.get( | ||
@@ -521,33 +548,15 @@ req.params.scriptId | ||
if (pathToSource) { | ||
let pathIsURL = false; | ||
try { | ||
pathIsURL = new URL(pathToSource).hostname == "localhost"; | ||
} catch {} | ||
if (pathIsURL) { | ||
http | ||
// $FlowFixMe[missing-local-annot] | ||
.get(pathToSource, (httpResponse) => { | ||
const { statusCode } = httpResponse; | ||
if (statusCode == 200) { | ||
httpResponse.setEncoding("utf8"); | ||
scriptSource = ""; | ||
httpResponse.on("data", (body) => { | ||
scriptSource += body; | ||
}); | ||
httpResponse.on("end", () => { | ||
sendResponse(); | ||
}); | ||
} else { | ||
scriptSource = `Fetching ${pathToSource} returned status ${statusCode}`; | ||
sendResponse(); | ||
httpResponse.resume(); | ||
} | ||
}) | ||
.on("error", (e) => { | ||
scriptSource = `Fetching ${pathToSource} failed with error ${e.message}`; | ||
sendResponse(); | ||
}); | ||
const httpURL = this._tryParseHTTPURL(pathToSource); | ||
if (httpURL) { | ||
this._fetchText(httpURL).then( | ||
(text) => sendSuccessResponse(text), | ||
(err) => | ||
sendErrorResponse( | ||
`Failed to fetch source url ${pathToSource}: ${err.message}` | ||
) | ||
); | ||
} else { | ||
let file; | ||
try { | ||
scriptSource = fs.readFileSync( | ||
file = fs.readFileSync( | ||
path.resolve(this._projectRoot, pathToSource), | ||
@@ -557,5 +566,9 @@ "utf8" | ||
} catch (err) { | ||
scriptSource = err.message; | ||
sendErrorResponse( | ||
`Failed to fetch source file ${pathToSource}: ${err.message}` | ||
); | ||
} | ||
sendResponse(); | ||
if (file) { | ||
sendSuccessResponse(file); | ||
} | ||
} | ||
@@ -574,3 +587,59 @@ } | ||
} | ||
_tryParseHTTPURL(url) { | ||
var _parsedURL; | ||
let parsedURL; | ||
try { | ||
parsedURL = new URL(url); | ||
} catch {} | ||
const protocol = | ||
(_parsedURL = parsedURL) === null || _parsedURL === void 0 | ||
? void 0 | ||
: _parsedURL.protocol; | ||
if (protocol !== "http:" && protocol !== "https:") { | ||
parsedURL = undefined; | ||
} | ||
return parsedURL; | ||
} | ||
// Fetch text, raising an exception if the text could not be fetched, | ||
// or is too large. | ||
async _fetchText(url) { | ||
if (url.hostname !== "localhost") { | ||
throw new Error("remote fetches not permitted"); | ||
} | ||
const response = await (0, _nodeFetch.default)(url); | ||
const text = await response.text(); | ||
// Restrict the length to well below the 500MB limit for nodejs (leaving | ||
// room some some later manipulation, e.g. base64 or wrapping in JSON) | ||
if (text.length > 350000000) { | ||
throw new Error("file too large to fetch via HTTP"); | ||
} | ||
return text; | ||
} | ||
_sendErrorToDebugger(message) { | ||
var _this$_debuggerConnec; | ||
const debuggerSocket = | ||
(_this$_debuggerConnec = this._debuggerConnection) === null || | ||
_this$_debuggerConnec === void 0 | ||
? void 0 | ||
: _this$_debuggerConnec.socket; | ||
if (debuggerSocket && debuggerSocket.readyState === _ws.default.OPEN) { | ||
debuggerSocket.send( | ||
JSON.stringify({ | ||
method: "Runtime.consoleAPICalled", | ||
params: { | ||
args: [ | ||
{ | ||
type: "string", | ||
value: message, | ||
}, | ||
], | ||
executionContextId: 0, | ||
type: "error", | ||
}, | ||
}) | ||
); | ||
} | ||
} | ||
} | ||
module.exports = Device; |
@@ -105,2 +105,3 @@ /** | ||
vm: page.vm, | ||
deviceName: device.getName(), | ||
}; | ||
@@ -107,0 +108,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63254
883
1
5
+ Addednode-fetch@^2.2.0
+ Addednode-fetch@2.7.0(transitive)
+ Addedtr46@0.0.3(transitive)
+ Addedwebidl-conversions@3.0.1(transitive)
+ Addedwhatwg-url@5.0.0(transitive)