microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
665fada6719d6178ed2679502c598c8a9b1eab00

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/appcenter/command/commandExecutor.ts

262lines · 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 * as vscode from "vscode";
5import * as Q from "q";
6import * as qs from "qs";
7import * as os from "os";
8
9import { ILogger, LogLevel } from "../../log/LogHelper";
10import Auth from "../../appcenter/auth/auth";
11import { AppCenterLoginType, ACConstants, AppCenterOS, CurrentAppDeployment } from "../appCenterConstants";
12import { Profile, getUser } from "../../appcenter/auth/profile/profile";
13import { SettingsHelper } from "../../settingsHelper";
14import { AppCenterClient, models } from "../api/index";
15import { DefaultApp, ICodePushReleaseParams } from "./commandParams";
16import { AppCenterExtensionManager } from "../appCenterExtensionManager";
17import { ACStrings } from "../appCenterStrings";
18import CodePushReleaseReact from "../codepush/releaseReact";
19import { ACUtils } from "../appCenterUtils";
20import { getQPromisifiedClientResult } from "../api/createClient";
21
22interface IAppCenterAuth {
23 login(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
24 logout(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
25 whoAmI(profile: Profile): Q.Promise<void>;
26}
27
28interface IAppCenterApps {
29 getCurrentApp(): Q.Promise<void>;
30 setCurrentApp(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
31
32 setCurrentDeployment(appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
33}
34
35interface IAppCenterCodePush {
36 releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
37}
38
39export class AppCenterCommandExecutor implements IAppCenterAuth, IAppCenterCodePush, IAppCenterApps {
40 private logger: ILogger;
41
42 constructor(logger: ILogger) {
43 this.logger = logger;
44 }
45
46 public login(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
47 const appCenterLoginOptions: string[] = Object.keys(AppCenterLoginType).filter(k => typeof AppCenterLoginType[k as any] === "number");
48 vscode.window.showQuickPick(appCenterLoginOptions, { placeHolder: ACStrings.SelectLoginTypeMsg })
49 .then((loginType) => {
50 switch (loginType) {
51 case (AppCenterLoginType[AppCenterLoginType.Interactive]):
52 vscode.window.showInformationMessage(ACStrings.PleaseLoginViaBrowser, "OK")
53 .then((selection: string) => {
54 if (selection.toLowerCase() === "ok") {
55 const loginUrl = `${SettingsHelper.getAppCenterLoginEndpoint()}?${qs.stringify({ hostname: os.hostname()})}`;
56 ACUtils.OpenUrl(loginUrl);
57 return vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken, ignoreFocusOut: true })
58 .then(token => {
59 this.loginWithToken(token, appCenterManager);
60 });
61 } else return Q.resolve(void 0);
62 });
63 break;
64 case (AppCenterLoginType[AppCenterLoginType.Token]):
65 vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken , ignoreFocusOut: true})
66 .then(token => {
67 this.loginWithToken(token, appCenterManager);
68 });
69 break;
70 default:
71 throw new Error("Unsupported login parameter!");
72 }
73 });
74 return Q.resolve(void 0);
75 }
76
77 public logout(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
78 const logoutOption = "Logout";
79 const logoutChoices: string[] = [logoutOption];
80 vscode.window.showQuickPick(logoutChoices, { placeHolder: ACStrings.LogoutPrompt })
81 .then((logoutType) => {
82 switch (logoutType) {
83 case (logoutOption):
84 return Auth.doLogout().then(() => {
85 vscode.window.showInformationMessage(ACStrings.UserLoggedOutMsg);
86 appCenterManager.setupNotAuthenticatedStatusBar();
87 return Q.resolve(void 0);
88 }).catch(() => {
89 this.logger.log("An errro occured on logout", LogLevel.Error);
90 });
91 default:
92 return Q.resolve(void 0);
93 }
94 });
95 return Q.resolve(void 0);
96 }
97
98 public whoAmI(profile: Profile): Q.Promise<void> {
99 if (profile && profile.displayName) {
100 vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
101 } else {
102 vscode.window.showInformationMessage(ACStrings.UserIsNotLoggedInMsg);
103 }
104 return Q.resolve(void 0);
105 }
106
107 public setCurrentDeployment(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
108 this.restoreCurrentApp().then((currentApp: DefaultApp) => {
109 if (currentApp && currentApp.currentAppDeployment && currentApp.currentAppDeployment.codePushDeployments) {
110 const deploymentOptions: string[] = currentApp.currentAppDeployment.codePushDeployments.map((deployment) => {
111 return deployment.name;
112 });
113 vscode.window.showQuickPick(deploymentOptions, { placeHolder: ACStrings.SelectCurrentDeploymentMsg })
114 .then((deploymentName) => {
115 if (deploymentName) {
116 this.saveCurrentApp(currentApp.identifier, AppCenterOS[currentApp.os], {
117 currentDeploymentName: deploymentName,
118 codePushDeployments: currentApp.currentAppDeployment.codePushDeployments,
119 }).then((app: DefaultApp | null) => {
120 if (app) {
121 appCenterManager.setCurrentDeploymentStatusBar(deploymentName);
122 }
123 });
124 }
125 });
126 } else {
127 appCenterManager.setCurrentDeploymentStatusBar(null);
128 }
129 });
130 return Q.resolve(void 0);
131 }
132
133 public getCurrentApp(): Q.Promise<void> {
134 this.restoreCurrentApp().then((app: DefaultApp) => {
135 if (app) {
136 vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(app.identifier));
137 } else {
138 vscode.window.showInformationMessage(ACStrings.NoCurrentAppSetMsg);
139 }
140 });
141 return Q.resolve(void 0);
142 }
143
144 public setCurrentApp(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
145 return getQPromisifiedClientResult(client.account.apps.list()).then((apps: models.AppResponse[]) => {
146 const appsList: models.AppResponse[] = apps;
147 const reactNativeApps = appsList.filter(app => app.platform === ACConstants.AppCenterReactNativePlatformName);
148 let options = reactNativeApps.map(app => {
149 return {
150 label: `${app.name} (${app.os})`,
151 description: app.displayName,
152 target: app.name,
153 };
154 });
155 vscode.window.showQuickPick(options, { placeHolder: ACStrings.ProvideCurrentAppPromptMsg })
156 .then((selected: {label: string, description: string, target: string}) => {
157 if (selected) {
158 const selectedApps: models.AppResponse[] = appsList.filter(app => app.name === selected.target);
159 if (selectedApps && selectedApps.length === 1) {
160 const selectedApp: models.AppResponse = selectedApps[0];
161 const selectedAppName: string = `${selectedApp.owner.name}/${selectedApp.name}`;
162 const OS: AppCenterOS = AppCenterOS[selectedApp.os];
163 getQPromisifiedClientResult(client.codepush.codePushDeployments.list(selectedApp.name, selectedApp.owner.name)).then((deployments: models.Deployment[]) => {
164 let currentDeployment: CurrentAppDeployment | null = null;
165 if (deployments.length > 0) {
166 currentDeployment = {
167 codePushDeployments: deployments,
168 currentDeploymentName: deployments[0].name, // Select 1st one by default
169 };
170 }
171 this.saveCurrentApp(selectedAppName, OS, currentDeployment).then((app: DefaultApp | null) => {
172 if (app) {
173 vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(selected.target));
174 appCenterManager.setCurrentAppStatusBar(ACUtils.formatAppNameForStatusBar(app));
175 }
176 });
177 });
178 }
179 }
180 return Q.resolve(void 0);
181 });
182 return Q.resolve(void 0);
183 });
184 }
185
186 public releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
187 const targetBinaryVersion = "1.0.0";
188 const deploymentName = "Staging";
189 const bundleZipPath = appCenterManager.projectRootPath; // TODO: create a bundle based on project root path
190
191 return this.restoreCurrentApp().then((currentApp: DefaultApp) => {
192 if (!currentApp) {
193 vscode.window.showWarningMessage(ACStrings.NoCurrentAppSetMsg);
194 return;
195 }
196 let codePushRelaseParams: ICodePushReleaseParams = {
197 app: currentApp,
198 appVersion: targetBinaryVersion,
199 deploymentName: deploymentName,
200 updatedContentZipPath: bundleZipPath,
201 };
202 CodePushReleaseReact.exec(client, codePushRelaseParams, this.logger);
203 });
204 }
205
206 private saveCurrentApp(currentAppName: string, appOS: AppCenterOS, currentAppDeployment: CurrentAppDeployment | null): Q.Promise<DefaultApp | null> {
207 const defaultApp = ACUtils.toDefaultApp(currentAppName, appOS, currentAppDeployment);
208 if (!defaultApp) {
209 vscode.window.showWarningMessage(ACStrings.InvalidCurrentAppNameMsg);
210 return Q.resolve(null);
211 }
212
213 let profile = getUser();
214 if (profile) {
215 profile.defaultApp = defaultApp;
216 profile.save();
217 return Q.resolve(defaultApp);
218 } else {
219 // No profile - not logged in?
220 vscode.window.showWarningMessage(ACStrings.UserIsNotLoggedInMsg);
221 return Q.resolve(null);
222 }
223 }
224
225 private restoreCurrentApp(): Q.Promise<DefaultApp | null> {
226 const user = getUser();
227 if (user) {
228 if (user.defaultApp) {
229 const currentApp = `${user.defaultApp.ownerName}/${user.defaultApp.appName}`;
230 const defaultApp: DefaultApp | null = ACUtils.toDefaultApp(currentApp, AppCenterOS[user.defaultApp.os], user.defaultApp.currentAppDeployment);
231 if (defaultApp) {
232 return Q.resolve(defaultApp);
233 }
234 }
235 }
236 return Q.resolve(null);
237 }
238
239 private loginWithToken(token: string | undefined, appCenterManager: AppCenterExtensionManager) {
240 if (!token) {
241 return;
242 }
243 return Auth.doTokenLogin(token).then((profile: Profile) => {
244 if (!profile) {
245 this.logger.log("Failed to fetch user info from server", LogLevel.Error);
246 vscode.window.showWarningMessage(ACStrings.FailedToExecuteLoginMsg);
247 return;
248 }
249 vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
250 appCenterManager.setuAuthenticatedStatusBar(profile.displayName);
251 this.restoreCurrentApp().then((currentApp: DefaultApp) => {
252 if (currentApp) {
253 appCenterManager.setCurrentAppStatusBar(ACUtils.formatAppNameForStatusBar(currentApp));
254 appCenterManager.setCurrentDeploymentStatusBar(currentApp.currentAppDeployment.currentDeploymentName);
255 } else {
256 appCenterManager.setCurrentAppStatusBar(null);
257 appCenterManager.setCurrentDeploymentStatusBar(null);
258 }
259 });
260 });
261 }
262}