// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import * as vscode from "vscode";
import * as Q from "q";
import * as qs from "qs";
import * as os from "os";
import { ILogger, LogLevel } from "../../log/LogHelper";
import Auth from "../../appcenter/auth/auth";
import { AppCenterLoginType } from "../appCenterConstants";
import { Profile, getUser } from "../../appcenter/auth/profile/profile";
import { SettingsHelper } from "../../settingsHelper";
import { AppCenterClient } from "../api/index";
import { DefaultApp, ICodePushReleaseParams } from "./commandParams";
import { AppCenterExtensionManager } from "../appCenterExtensionManager";
import { ACStrings } from "../appCenterStrings";
import CodePushReleaseReact from "../codepush/releaseReact";
import { ACUtils } from "../appCenterUtils";
interface IAppCenterAuth {
login(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
logout(appcenterManager: AppCenterExtensionManager): Q.Promise<void>;
whoAmI(): Q.Promise<void>;
}
interface IAppCenterApps {
getCurrentApp(): Q.Promise<void>;
setCurrentApp(appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
}
interface IAppCenterCodePush {
releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void>;
}
export class AppCenterCommandExecutor implements IAppCenterAuth, IAppCenterCodePush, IAppCenterApps {
private logger: ILogger;
constructor(logger: ILogger) {
this.logger = logger;
}
public login(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
const appCenterLoginOptions: string[] = Object.keys(AppCenterLoginType).filter(k => typeof AppCenterLoginType[k as any] === "number");
vscode.window.showQuickPick(appCenterLoginOptions, { placeHolder: ACStrings.SelectLoginTypeMsg })
.then((loginType) => {
switch (loginType) {
case (AppCenterLoginType[AppCenterLoginType.Interactive]):
vscode.window.showInformationMessage(ACStrings.PleaseLoginViaBrowser, "OK")
.then((selection: string) => {
if (selection.toLowerCase() === "ok") {
const loginUrl = `${SettingsHelper.getAppCenterLoginEndpoint()}?${qs.stringify({ hostname: os.hostname()})}`;
ACUtils.OpenUrl(loginUrl);
return vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken, ignoreFocusOut: true })
.then(token => {
this.loginWithToken(token, appCenterManager);
});
} else return Q.resolve(void 0);
});
break;
case (AppCenterLoginType[AppCenterLoginType.Token]):
vscode.window.showInputBox({ prompt: ACStrings.PleaseProvideToken , ignoreFocusOut: true})
.then(token => {
this.loginWithToken(token, appCenterManager);
});
break;
default:
throw new Error("Unsupported login parameter!");
}
});
return Q.resolve(void 0);
}
public logout(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
const logoutOption = "Logout";
const logoutChoices: string[] = [logoutOption];
vscode.window.showQuickPick(logoutChoices, { placeHolder: ACStrings.LogoutPrompt })
.then((logoutType) => {
switch (logoutType) {
case (logoutOption):
return Auth.doLogout().then(() => {
vscode.window.showInformationMessage(ACStrings.UserLoggedOutMsg);
appCenterManager.setupNotAuthenticatedStatusBar();
return Q.resolve(void 0);
}).catch(() => {
this.logger.log("An errro occured on logout", LogLevel.Error);
});
default:
return Q.resolve(void 0);
}
});
return Q.resolve(void 0);
}
public whoAmI(): Q.Promise<void> {
return Auth.whoAmI().then((profile: Profile) => {
if (profile.displayName) {
vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
return;
}
}).catch(() => {
vscode.window.showInformationMessage(ACStrings.UserIsNotLoggedInMsg);
return;
});
}
public getCurrentApp(): Q.Promise<void> {
this.restoreCurrentApp().then((app: DefaultApp) => {
vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(app.identifier));
}).catch(e => {
vscode.window.showInformationMessage(ACStrings.NoCurrentAppSetMsg);
});
return Q.resolve(void 0);
}
public setCurrentApp(appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
vscode.window.showInputBox({ prompt: ACStrings.ProvideCurrentAppPromptMsg, ignoreFocusOut: true })
.then((currentApp: string) => {
// TODO: I believe we should validate app here for existance! before we save anything
this.saveCurrentApp(<string>currentApp).then((saved: boolean) => {
if (saved) {
vscode.window.showInformationMessage(ACStrings.YourCurrentAppMsg(currentApp));
appCenterManager.setCurrentAppStatusBar(currentApp);
}
});
});
return Q.resolve(void 0);
}
public releaseReact(client: AppCenterClient, appCenterManager: AppCenterExtensionManager): Q.Promise<void> {
const targetBinaryVersion = "1.0.0";
const deploymentName = "Staging";
const bundleZipPath = appCenterManager.projectRootPath; // TODO: create a bundle based on project root path
return this.restoreCurrentApp().then((currentApp: DefaultApp) => {
if (!currentApp) {
vscode.window.showInformationMessage(ACStrings.NoCurrentAppSetMsg);
return;
}
let codePushRelaseParams: ICodePushReleaseParams = {
app: currentApp,
appVersion: targetBinaryVersion,
deploymentName: deploymentName,
updatedContentZipPath: bundleZipPath,
};
CodePushReleaseReact.exec(client, codePushRelaseParams, this.logger);
});
}
private saveCurrentApp(currentApp: string): Q.Promise<boolean> {
const defaultApp = ACUtils.toDefaultApp(currentApp);
if (!defaultApp) {
vscode.window.showInformationMessage(ACStrings.InvalidCurrentAppNameMsg);
return Q<boolean>(false);
}
let profile = getUser();
if (profile) {
profile.defaultApp = defaultApp;
profile.save();
return Q<boolean>(true);
} else {
// No profile - not logged in?
vscode.window.showInformationMessage(ACStrings.UserIsNotLoggedInMsg);
return Q<boolean>(false);
}
}
private restoreCurrentApp(): Q.Promise<DefaultApp | null> {
const user = getUser();
if (user) {
const currentApp = user.defaultApp
? `${user.defaultApp.ownerName}/${user.defaultApp.appName}`
: "";
const defaultApp: DefaultApp | null = ACUtils.toDefaultApp(currentApp);
if (defaultApp) {
return Q.resolve(defaultApp);
}
}
return Q.resolve(null);
}
private loginWithToken(token: string | undefined, appCenterManager: AppCenterExtensionManager) {
if (!token) {
return;
}
return Auth.doTokenLogin(token).then((profile: Profile) => {
vscode.window.showInformationMessage(ACStrings.YouAreLoggedInMsg(profile.displayName));
appCenterManager.setuAuthenticatedStatusBar(profile.displayName);
this.restoreCurrentApp().then((currentApp: DefaultApp) => {
if (currentApp) {
appCenterManager.setCurrentAppStatusBar(currentApp.identifier);
} else {
appCenterManager.setCurrentAppStatusBar(null);
}
});
});
}
}microsoft/vscode-react-native
Publicmirrored from https://github.com/microsoft/vscode-react-nativeAvailable
src/extension/appcenter/command/commandExecutor.ts
198lines · modepreview