microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e3ae42278f91179dcf2a3c6389a8dcf0e8a76c13

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/debugger/scriptImporter.ts

102lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import {FileSystem} from "../common/node/fileSystem";
5import {Log} from "../common/log/log";
6import {LogLevel} from "../common/log/logHelper";
7import {Packager} from "../common/packager";
8import path = require("path");
9import Q = require("q");
10import {Request} from "../common/node/request";
11import {SourceMapUtil} from "./sourceMap";
12import url = require("url");
13
14interface DownloadedScript {
15 contents: string;
16 filepath: string;
17}
18
19export class ScriptImporter {
20 public static DEBUGGER_WORKER_FILE_BASENAME = "debuggerWorker";
21 public static DEBUGGER_WORKER_FILENAME = ScriptImporter.DEBUGGER_WORKER_FILE_BASENAME + ".js";
22 private packagerPort: number;
23 private sourcesStoragePath: string;
24 private sourceMapUtil: SourceMapUtil;
25
26 constructor(packagerPort: number, sourcesStoragePath: string) {
27 this.packagerPort = packagerPort;
28 this.sourcesStoragePath = sourcesStoragePath;
29 this.sourceMapUtil = new SourceMapUtil();
30 }
31
32 public downloadAppScript(scriptUrlString: string, debugAdapterPort: number): Q.Promise<DownloadedScript> {
33 const overridenScriptUrlString = this.overridePackagerPort(scriptUrlString);
34 console.log("overriden " + overridenScriptUrlString);
35 // We'll get the source code, and store it locally to have a better debugging experience
36 return new Request().request(overridenScriptUrlString, true).then(scriptBody => {
37 // Extract sourceMappingURL from body
38 let scriptUrl = url.parse(overridenScriptUrlString); // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
39 let sourceMappingUrl = this.sourceMapUtil.getSourceMapURL(scriptUrl, scriptBody); // sourceMappingUrl = "http://localhost:8081/index.ios.map?platform=ios&dev=true"
40
41 let waitForSourceMapping = Q<void>(null);
42 if (sourceMappingUrl) {
43 /* handle source map - request it and store it locally */
44 waitForSourceMapping = this.writeAppSourceMap(sourceMappingUrl, scriptUrl)
45 .then(() => {
46 scriptBody = this.sourceMapUtil.updateScriptPaths(scriptBody, sourceMappingUrl);
47 });
48 }
49
50 return waitForSourceMapping
51 .then(() => this.writeAppScript(scriptBody, scriptUrl))
52 .then((scriptFilePath: string) => {
53 Log.logInternalMessage(LogLevel.Info, `Script ${overridenScriptUrlString} downloaded to ${scriptFilePath}`);
54 return { contents: scriptBody, filepath: scriptFilePath };
55 }).finally(() => {
56 // Request that the debug adapter update breakpoints and sourcemaps now that we have written them
57 return new Request().request(`http://localhost:${debugAdapterPort}/refreshBreakpoints`);
58 });
59 });
60 }
61
62 public downloadDebuggerWorker(sourcesStoragePath: string): Q.Promise<void> {
63 let debuggerWorkerURL = `http://${Packager.getHostForPort(this.packagerPort)}/${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
64 let debuggerWorkerLocalPath = path.join(sourcesStoragePath, ScriptImporter.DEBUGGER_WORKER_FILENAME);
65 Log.logInternalMessage(LogLevel.Info, "About to download: " + debuggerWorkerURL + " to: " + debuggerWorkerLocalPath);
66 return new Request().request(debuggerWorkerURL, true).then((body: string) => {
67 return new FileSystem().writeFile(debuggerWorkerLocalPath, body);
68 });
69 }
70
71 /**
72 * Writes the script file to the project temporary location.
73 */
74 private writeAppScript(scriptBody: string, scriptUrl: url.Url): Q.Promise<String> {
75 let scriptFilePath = path.join(this.sourcesStoragePath, scriptUrl.pathname); // scriptFilePath = "$TMPDIR/index.ios.bundle"
76 return new FileSystem().writeFile(scriptFilePath, scriptBody)
77 .then(() => scriptFilePath);
78 }
79
80 /**
81 * Writes the source map file to the project temporary location.
82 */
83 private writeAppSourceMap(sourceMapUrl: url.Url, scriptUrl: url.Url): Q.Promise<void> {
84 return new Request().request(sourceMapUrl.href, true)
85 .then((sourceMapBody: string) => {
86 let sourceMappingLocalPath = path.join(this.sourcesStoragePath, sourceMapUrl.pathname); // sourceMappingLocalPath = "$TMPDIR/index.ios.map"
87 let scriptFileRelativePath = path.basename(scriptUrl.pathname); // scriptFileRelativePath = "index.ios.bundle"
88 let updatedContent = this.sourceMapUtil.updateSourceMapFile(sourceMapBody, scriptFileRelativePath, this.sourcesStoragePath);
89 return new FileSystem().writeFile(sourceMappingLocalPath, updatedContent);
90 });
91 }
92
93 /**
94 * Changes the port of the url to be the one configured as this.packagerPort
95 */
96 private overridePackagerPort(urlToOverride: string): string {
97 let components = url.parse(urlToOverride);
98 components.port = this.packagerPort.toString();
99 delete components.host; // We delete the host, if not the port change will be ignored
100 return url.format(components);
101 }
102}
103