microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
bb685befdbe7e88c8b5573661cf3dfa5d48a4001

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/appcenter/command/commandExecutor.ts

198lines · 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 } from "../appCenterConstants";
12import { Profile, getUser } from "../../appcenter/auth/profile/profile";
13import { SettingsHelper } from "../../settingsHelper";
14import { AppCenterClient } 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";
20
21interface IAppCenterAuth {
22 login(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
23 logout(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
24 whoAmI(): Q.Promise<void>;
25}
26
27interface IAppCenterApps {
28 getCurrentApp(): Q.Promise<void>;
29 setCurrentApp(appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
30}
31
32interface IAppCenterCodePush {
33 releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
34}
35
36export class AppCenterCommandExecutor implements IAppCenterAuth, IAppCenterCodePush, IAppCenterApps {
37 private logger: ILogger;
38
39 constructor(logger: ILogger) {
40 this.logger = logger;
41 }
42
43 public login(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
44 const appCenterLoginOptions: string[] = Object.keys(AppCenterLoginType).filter(k => typeof AppCenterLoginType[k as any] === "number");
45 vscode.window.showQuickPick(appCenterLoginOptions, { placeHolder: ACStrings.SelectLoginTypeMsg })
46 .then((loginType) => {
47 switch (loginType) {
48 case (AppCenterLoginType[AppCenterLoginType.Interactive]):
49 vscode.window.showInformationMessage(ACStrings.PleaseLoginViaBrowser, "OK")
50 .then((selection: string) => {
51 if (selection.toLowerCase() === "ok") {
52 const loginUrl = `${SettingsHelper.getAppCenterLoginEndpoint()}?${qs.stringify({ hostname: os.hostname()})}`;
53 ACUtils.OpenUrl(loginUrl);
54 return vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken, ignoreFocusOut: true })
55 .then(token => {
56 this.loginWithToken(token, appCenterManager);
57 });
58 } else return Q.resolve(void 0);
59 });
60 break;
61 case (AppCenterLoginType[AppCenterLoginType.Token]):
62 vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken , ignoreFocusOut: true})
63 .then(token => {
64 this.loginWithToken(token, appCenterManager);
65 });
66 break;
67 default:
68 throw new Error("Unsupported login parameter!");
69 }
70 });
71 return Q.resolve(void 0);
72 }
73
74 public logout(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
75 const logoutOption = "Logout";
76 const logoutChoices: string[] = [logoutOption];
77 vscode.window.showQuickPick(logoutChoices, { placeHolder: ACStrings.LogoutPrompt })
78 .then((logoutType) => {
79 switch (logoutType) {
80 case (logoutOption):
81 return Auth.doLogout().then(() => {
82 vscode.window.showInformationMessage(ACStrings.UserLoggedOutMsg);
83 appCenterManager.setupNotAuthenticatedStatusBar();
84 return Q.resolve(void 0);
85 }).catch(() => {
86 this.logger.log("An errro occured on logout", LogLevel.Error);
87 });
88 default:
89 return Q.resolve(void 0);
90 }
91 });
92 return Q.resolve(void 0);
93 }
94
95 public whoAmI(): Q.Promise<void> {
96 return Auth.whoAmI().then((profile: Profile) => {
97 if (profile.displayName) {
98 vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
99 return;
100 }
101 }).catch(() => {
102 vscode.window.showInformationMessage(ACStrings.UserIsNotLoggedInMsg);
103 return;
104 });
105 }
106
107 public getCurrentApp(): Q.Promise<void> {
108 this.restoreCurrentApp().then((app: DefaultApp) => {
109 vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(app.identifier));
110 }).catch(e => {
111 vscode.window.showInformationMessage(ACStrings.NoCurrentAppSetMsg);
112 });
113 return Q.resolve(void 0);
114 }
115
116 public setCurrentApp(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
117 vscode.window.showInputBox({ prompt: ACStrings.ProvideCurrentAppPromptMsg, ignoreFocusOut: true })
118 .then((currentApp: string) => {
119 // TODO: I believe we should validate app here for existance! before we save anything
120 this.saveCurrentApp(<string>currentApp).then((saved: boolean) => {
121 if (saved) {
122 vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(currentApp));
123 appCenterManager.setCurrentAppStatusBar(currentApp);
124 }
125 });
126 });
127 return Q.resolve(void 0);
128 }
129
130 public releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
131 const targetBinaryVersion = "1.0.0";
132 const deploymentName = "Staging";
133 const bundleZipPath = appCenterManager.projectRootPath; // TODO: create a bundle based on project root path
134
135 return this.restoreCurrentApp().then((currentApp: DefaultApp) => {
136 if (!currentApp) {
137 vscode.window.showInformationMessage(ACStrings.NoCurrentAppSetMsg);
138 return;
139 }
140 let codePushRelaseParams: ICodePushReleaseParams = {
141 app: currentApp,
142 appVersion: targetBinaryVersion,
143 deploymentName: deploymentName,
144 updatedContentZipPath: bundleZipPath,
145 };
146 CodePushReleaseReact.exec(client, codePushRelaseParams, this.logger);
147 });
148 }
149
150 private saveCurrentApp(currentApp: string): Q.Promise<boolean> {
151 const defaultApp = ACUtils.toDefaultApp(currentApp);
152 if (!defaultApp) {
153 vscode.window.showInformationMessage(ACStrings.InvalidCurrentAppNameMsg);
154 return Q<boolean>(false);
155 }
156 let profile = getUser();
157 if (profile) {
158 profile.defaultApp = defaultApp;
159 profile.save();
160 return Q<boolean>(true);
161 } else {
162 // No profile - not logged in?
163 vscode.window.showInformationMessage(ACStrings.UserIsNotLoggedInMsg);
164 return Q<boolean>(false);
165 }
166 }
167
168 private restoreCurrentApp(): Q.Promise<DefaultApp | null> {
169 const user = getUser();
170 if (user) {
171 const currentApp = user.defaultApp
172 ? `${user.defaultApp.ownerName}/${user.defaultApp.appName}`
173 : "";
174 const defaultApp: DefaultApp | null = ACUtils.toDefaultApp(currentApp);
175 if (defaultApp) {
176 return Q.resolve(defaultApp);
177 }
178 }
179 return Q.resolve(null);
180 }
181
182 private loginWithToken(token: string | undefined, appCenterManager: AppCenterExtensionManager) {
183 if (!token) {
184 return;
185 }
186 return Auth.doTokenLogin(token).then((profile: Profile) => {
187 vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
188 appCenterManager.setuAuthenticatedStatusBar(profile.displayName);
189 this.restoreCurrentApp().then((currentApp: DefaultApp) => {
190 if (currentApp) {
191 appCenterManager.setCurrentAppStatusBar(currentApp.identifier);
192 } else {
193 appCenterManager.setCurrentAppStatusBar(null);
194 }
195 });
196 });
197 }
198}