microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
876df2a0c1922138b98749a03b17d6aebb0d5d7a

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/scriptImporter.ts

92lines · 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
4// TODO: I'll rename this file to scriptDownloader.ts before pushing the PR
5import fs = require("fs");
6import {Log} from "../utils/commands/log";
7import path = require("path");
8import Q = require("q");
9import {Request} from "../utils/node/request";
10import {SourceMapUtil} from "../utils/sourceMap";
11import url = require("url");
12
13interface DownloadedScript {
14 contents: string;
15 filepath: string;
16}
17
18export class ScriptImporter {
19 private sourcesStoragePath: string;
20 private sourceMapUtil: SourceMapUtil;
21
22 constructor(sourcesStoragePath: string) {
23 this.sourcesStoragePath = sourcesStoragePath;
24 this.sourceMapUtil = new SourceMapUtil();
25 }
26
27 public download(scriptUrlString: string): Q.Promise<DownloadedScript> {
28
29 // We'll get the source code, and store it locally to have a better debugging experience
30 return new Request().request(scriptUrlString, true).then(scriptBody => {
31 // Extract sourceMappingURL from body
32 let scriptUrl = url.parse(scriptUrlString); // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
33 let sourceMappingUrl = this.sourceMapUtil.getSourceMapURL(scriptUrl, scriptBody); // sourceMappingUrl = "http://localhost:8081/index.ios.map?platform=ios&dev=true"
34
35 let waitForSourceMapping = Q<void>(null);
36 if (sourceMappingUrl) {
37 /* handle source map - request it and store it locally */
38 waitForSourceMapping = this.writeSourceMap(sourceMappingUrl, scriptUrl)
39 .then(() => {
40 scriptBody = this.sourceMapUtil.updateScriptPaths(scriptBody, sourceMappingUrl);
41 });
42 }
43
44 return waitForSourceMapping
45 .then(() => this.writeScript(scriptBody, scriptUrl))
46 .then((scriptFilePath: string) => {
47 Log.logInternalMessage(`Script ${scriptUrlString} downloaded to ${scriptFilePath}`);
48 return { contents: scriptBody, filepath: scriptFilePath };
49 });
50 });
51 }
52
53 /**
54 * Writes the script file to the project temporary location.
55 */
56 private writeScript(scriptBody: string, scriptUrl: url.Url): Q.Promise<String> {
57 return Q.fcall(() => {
58 let scriptFilePath = path.join(this.sourcesStoragePath, scriptUrl.pathname); // scriptFilePath = "$TMPDIR/index.ios.bundle"
59 this.writeTemporaryFileSync(scriptFilePath, scriptBody);
60 return scriptFilePath;
61 });
62 }
63
64 /**
65 * Writes the source map file to the project temporary location.
66 */
67 private writeSourceMap(sourceMapUrl: url.Url, scriptUrl: url.Url): Q.Promise<void> {
68 return new Request().request(sourceMapUrl.href, true)
69 .then((sourceMapBody: string) => {
70 let sourceMappingLocalPath = path.join(this.sourcesStoragePath, sourceMapUrl.pathname); // sourceMappingLocalPath = "$TMPDIR/index.ios.map"
71 let scriptFileRelativePath = path.basename(scriptUrl.pathname); // scriptFileRelativePath = "index.ios.bundle"
72 this.writeTemporaryFileSync(sourceMappingLocalPath, this.sourceMapUtil.updateSourceMapFile(sourceMapBody, scriptFileRelativePath, this.sourcesStoragePath));
73 });
74 }
75
76 private writeTemporaryFileSync(filename: string, data: string): Q.Promise<void> {
77 let writeFile = Q.nfbind<void>(fs.writeFile);
78
79 return writeFile(filename, data)
80 .then(() => this.scheduleTemporaryFileCleanUp(filename));
81 }
82
83 private scheduleTemporaryFileCleanUp(filename: string): void {
84 process.on("exit", function() {
85 let unlink = Q.nfbind<void>(fs.unlink);
86 unlink(filename)
87 .then(() => {
88 Log.logMessage("Succesfully cleaned temporary file: " + filename);
89 });
90 });
91 }
92}