-
Notifications
You must be signed in to change notification settings - Fork 261
/
installExpoGoApplication.ts
166 lines (149 loc) · 6.76 KB
/
installExpoGoApplication.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import * as assert from "assert";
import * as fs from "fs";
import * as https from "https";
import * as os from "os";
import * as vscode from "vscode";
import * as nls from "vscode-nls";
import { OutputChannelLogger } from "../log/OutputChannelLogger";
import { ErrorHelper } from "../../common/error/errorHelper";
import { InternalErrorCode } from "../../common/error/internalErrorCode";
import { downloadExpoGo } from "../../common/downloadHelper";
import { installAndroidApplication, installiOSApplication } from "../../common/installHelper";
import { Command } from "./util/command";
nls.config({
messageFormat: nls.MessageFormat.bundle,
bundleFormat: nls.BundleFormat.standalone,
})();
const localize = nls.loadMessageBundle();
const logger = OutputChannelLogger.getMainChannel();
export class InstallExpoGoApplication extends Command {
codeName = "installExpoGoApplication";
label = "Download and install Expo Go on simulator or device";
error = ErrorHelper.getInternalError(InternalErrorCode.FailedToInstallExpoGo);
async baseFn(): Promise<void> {
assert(this.project);
const item = await vscode.window.showQuickPick(["Android", "iOS"], {
placeHolder: "Select type for mobile OS",
});
const installItem = await vscode.window.showQuickPick(["Manual", "Auto"], {
placeHolder: "How to install application",
});
const expoHelper = this.project.getExponentHelper();
logger.info(localize("CheckExpoEnvironment", "Checking Expo project environment."));
const isExpo = await expoHelper.isExpoManagedApp(true);
const expoGoListAPI = "https://api.expo.dev/v2/versions";
const apiJson = await fetchJson(expoGoListAPI);
const jsonContent = JSON.parse(apiJson);
if (isExpo) {
const currentSdkVersion = await expoHelper.exponentSdk(true);
const expoUrlInfo = jsonContent.sdkVersions[currentSdkVersion];
if (item == "Android") {
void vscode.window.showInformationMessage("Downloading Expo Go for Android.");
logger.logStream(
localize("DownloadAndroidExpoGo", "\nDownloading Expo Go for Android. \n"),
);
const targetUrl = expoUrlInfo.androidClientUrl;
const androidClientVersion = expoUrlInfo.androidClientVersion as string;
const fileName = `${this.project
.getPackager()
.getProjectPath()}/expogo_${androidClientVersion}.apk`;
if (!fs.existsSync(fileName)) {
try {
await downloadExpoGo(targetUrl, fileName);
} catch {
throw new Error(
localize("FailedToDownloadExpoGo", "Failed to download Expo Go."),
);
}
}
if (installItem == "Auto") {
try {
await installAndroidApplication(this.project, fileName);
} catch {
throw new Error(
localize("FailedToInstallExpoGo", "Failed to install Expo Go."),
);
}
} else {
logger.logStream(
localize(
"ManualInstall",
"Please manually install Expo Go from project root path. \n",
),
);
}
} else if (item == "iOS") {
if (os.platform() != "darwin") {
logger.warning(
localize(
"NotDarwinPlatform",
"Current OS may not support iOS installer. The Expo Go may not be installed.\n",
),
);
}
void vscode.window.showInformationMessage("Downloading Expo Go for iOS.");
logger.logStream(
localize("DownloadiOSExpoGo", "\nDownloading Expo Go for iOS. \n"),
);
const targetUrl = expoUrlInfo.iosClientUrl;
const iOSClientVersion = expoUrlInfo.iosClientVersion as string;
const tarFile = `${this.project
.getPackager()
.getProjectPath()}/expogo_${iOSClientVersion}.tar.gz`;
if (!fs.existsSync(tarFile)) {
try {
await downloadExpoGo(
targetUrl,
`${this.project
.getPackager()
.getProjectPath()}/expogo_${iOSClientVersion}.tar.gz`,
);
} catch {
throw new Error(
localize("FailedToDownloadExpoGo", "Failed to download Expo Go."),
);
}
}
if (installItem == "Auto" && os.platform() == "darwin") {
try {
await installiOSApplication(this.project, tarFile);
} catch {
throw new Error(
localize("FailedToInstallExpoGo", "Failed to install Expo Go."),
);
}
} else {
logger.logStream(
localize(
"CannotAutoInstall",
"Cannot auto install Expo Go, selected manual install or target machine is not MacOS. \n",
),
);
}
} else {
return;
}
} else {
throw new Error(localize("NotExpoProject", "Current project is not Expo managed."));
}
}
}
async function fetchJson(url: string): Promise<string> {
return new Promise<string>((fulfill, reject) => {
const requestOptions: https.RequestOptions = {};
requestOptions.rejectUnauthorized = false; // CodeQL [js/disabling-certificate-validation] Debug extension does not need to verify certificate
const request = https.get(url, requestOptions, response => {
let data = "";
response.setEncoding("utf8");
response.on("data", (chunk: string) => {
data += chunk;
});
response.on("end", () => fulfill(data));
response.on("error", reject);
});
request.on("error", reject);
request.end();
});
}