teamsfx-extension
Version:
Create, debug, and deploy Teams apps with Teams Toolkit
930 lines • 44.6 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.selectSubscription = exports.signInM365 = exports.signInAzure = exports.signOutM365 = exports.signOutAzure = exports.cmpAccountsHandler = exports.showError = exports.cmdHdlDisposeTreeView = exports.cmdHdlLoadTreeView = exports.openAzureAccountHandler = exports.openM365AccountHandler = exports.openManifestHandler = exports.openReportIssues = exports.openBotManagement = exports.openAppManagement = exports.openSamplesHandler = exports.openWelcomeHandler = exports.openDocumentHandler = exports.preDebugCheckHandler = exports.backendExtensionsInstallHandler = exports.validateSpfxDependenciesHandler = exports.validateDependenciesHandler = exports.addCapabilityHandler = exports.updateAADHandler = exports.detectVsCodeEnv = exports.runCommand = exports.publishHandler = exports.deployHandler = exports.provisionHandler = exports.buildPackageHandler = exports.validateManifestHandler = exports.updateProjectHandler = exports.createNewProjectHandler = exports.activate = exports.core = void 0;
const vscode_1 = require("vscode");
const teamsfx_api_1 = require("@microsoft/teamsfx-api");
const teamsfx_core_1 = require("@microsoft/teamsfx-core");
const userInterface_1 = require("./userInterface");
const graphLogin_1 = require("./commonlib/graphLogin");
const azureLogin_1 = require("./commonlib/azureLogin");
const appStudioLogin_1 = require("./commonlib/appStudioLogin");
const appStudioCodeSpaceLogin_1 = require("./commonlib/appStudioCodeSpaceLogin");
const log_1 = require("./commonlib/log");
const telemetry_1 = require("./commonlib/telemetry");
const commandsTreeViewProvider_1 = require("./commandsTreeViewProvider");
const extensionPackage = require("./../package.json");
const extensionVariables_1 = require("./extensionVariables");
const extTelemetry_1 = require("./telemetry/extTelemetry");
const extTelemetryEvents_1 = require("./telemetry/extTelemetryEvents");
const commonUtils = require("./debug/commonUtils");
const error_1 = require("./error");
const webviewPanel_1 = require("./controls/webviewPanel");
const constants = require("./debug/constants");
const commonUtils_1 = require("./utils/commonUtils");
const fs = require("fs-extra");
const vscode = require("vscode");
const checker_1 = require("./debug/depsChecker/checker");
const backendExtensionsInstall_1 = require("./debug/depsChecker/backendExtensionsInstall");
const dotnetChecker_1 = require("./debug/depsChecker/dotnetChecker");
const util = require("util");
const StringResources = require("./resources/Strings.json");
const vscodeAdapter_1 = require("./debug/depsChecker/vscodeAdapter");
const vscodeLogger_1 = require("./debug/depsChecker/vscodeLogger");
const vscodeTelemetry_1 = require("./debug/depsChecker/vscodeTelemetry");
const PanelType_1 = require("./controls/PanelType");
const constant_1 = require("./commonlib/common/constant");
const azureNodeChecker_1 = require("./debug/depsChecker/azureNodeChecker");
const spfxNodeChecker_1 = require("./debug/depsChecker/spfxNodeChecker");
const teamsfxTaskHandler_1 = require("./debug/teamsfxTaskHandler");
const vsc_ui_1 = require("./qm/vsc_ui");
const runningTasks = new Set(); // to control state of task execution
function activate() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const result = teamsfx_api_1.ok(null);
try {
exports.core = teamsfx_core_1.CoreProxy.getInstance();
{
const result = yield exports.core.withDialog(userInterface_1.default);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const result = yield exports.core.withGraphToken(graphLogin_1.default);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
azureLogin_1.default.setStatusChangeMap("successfully-sign-in-azure", (status, token, accountInfo) => {
if (status === constant_1.signedIn) {
vscode_1.window.showInformationMessage(StringResources.vsc.handlers.azureSignIn);
}
else if (status === constant_1.signedOut) {
vscode_1.window.showInformationMessage(StringResources.vsc.handlers.azureSignOut);
}
return Promise.resolve();
}, false);
const result = yield exports.core.withAzureAccount(azureLogin_1.default);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
let appstudioLogin = appStudioLogin_1.default;
const vscodeEnv = detectVsCodeEnv();
if (vscodeEnv === teamsfx_api_1.VsCodeEnv.codespaceBrowser || vscodeEnv === teamsfx_api_1.VsCodeEnv.codespaceVsCode) {
appstudioLogin = appStudioCodeSpaceLogin_1.default;
}
appstudioLogin.setStatusChangeMap("successfully-sign-in-m365", (status, token, accountInfo) => {
if (status === constant_1.signedIn) {
vscode_1.window.showInformationMessage(StringResources.vsc.handlers.m365SignIn);
}
else if (status === constant_1.signedOut) {
vscode_1.window.showInformationMessage(StringResources.vsc.handlers.m365SignOut);
}
return Promise.resolve();
}, false);
const result = yield exports.core.withAppStudioToken(appstudioLogin);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const telemetry = new telemetry_1.VSCodeTelemetryReporter(extensionPackage.aiKey, extensionPackage.version, extensionPackage.name);
const result = yield exports.core.withTelemetry(telemetry);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const result = yield exports.core.withLogger(log_1.default);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const result = yield exports.core.withTreeProvider(commandsTreeViewProvider_1.default.getTreeView("teamsfx-accounts"));
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const globalConfig = new teamsfx_api_1.ConfigMap();
globalConfig.set("function-dotnet-checker-enabled", vscodeAdapter_1.vscodeAdapter.dotnetCheckerEnabled());
const result = yield exports.core.init(globalConfig);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
const workspacePath = ((_a = vscode_1.workspace.workspaceFolders) === null || _a === void 0 ? void 0 : _a.length)
? vscode_1.workspace.workspaceFolders[0].uri.fsPath
: undefined;
const result = yield exports.core.open(workspacePath);
if (result.isErr()) {
showError(result.error);
return teamsfx_api_1.err(result.error);
}
}
{
yield openMarkdownHandler();
}
}
catch (e) {
const FxError = {
name: e.name,
source: error_1.ExtensionSource,
message: e.message,
stack: e.stack,
timestamp: new Date(),
};
showError(FxError);
return teamsfx_api_1.err(FxError);
}
return result;
});
}
exports.activate = activate;
function createNewProjectHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.CreateProjectStart, getTriggerFromProperty(args));
return yield runCommand(teamsfx_api_1.Stage.create);
});
}
exports.createNewProjectHandler = createNewProjectHandler;
function updateProjectHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.UpdateProjectStart, getTriggerFromProperty(args));
return yield runCommand(teamsfx_api_1.Stage.update);
});
}
exports.updateProjectHandler = updateProjectHandler;
function validateManifestHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ValidateManifestStart, getTriggerFromProperty(args));
const func = {
namespace: "fx-solution-azure",
method: "validateManifest",
};
const result = yield exports.core.executeUserTask(func);
if (result.isErr()) {
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.ValidateManifest, result.error);
}
else {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ValidateManifest, {
[extTelemetryEvents_1.TelemetryProperty.Success]: extTelemetryEvents_1.TelemetrySuccess.Yes,
});
}
return result;
});
}
exports.validateManifestHandler = validateManifestHandler;
function buildPackageHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.BuildStart, getTriggerFromProperty(args));
const func = {
namespace: "fx-solution-azure",
method: "buildPackage",
};
const result = yield exports.core.executeUserTask(func);
if (result.isErr()) {
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.Build, result.error);
}
else {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.Build, {
[extTelemetryEvents_1.TelemetryProperty.Success]: extTelemetryEvents_1.TelemetrySuccess.Yes,
});
}
return result;
});
}
exports.buildPackageHandler = buildPackageHandler;
function provisionHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ProvisionStart, getTriggerFromProperty(args));
return yield runCommand(teamsfx_api_1.Stage.provision);
});
}
exports.provisionHandler = provisionHandler;
function deployHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.DeployStart, getTriggerFromProperty(args));
return yield runCommand(teamsfx_api_1.Stage.deploy);
});
}
exports.deployHandler = deployHandler;
function publishHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.PublishStart, getTriggerFromProperty(args));
return yield runCommand(teamsfx_api_1.Stage.publish);
});
}
exports.publishHandler = publishHandler;
const coreExeceutor = function (func, answers) {
return __awaiter(this, void 0, void 0, function* () {
return yield exports.core.callFunc(func, answers);
});
};
function runCommand(stage) {
return __awaiter(this, void 0, void 0, function* () {
const eventName = extTelemetry_1.ExtTelemetry.stageToEvent(stage);
let result = teamsfx_api_1.ok(null);
try {
// 1. check concurrent lock
if (runningTasks.size > 0 && stage !== teamsfx_api_1.Stage.create) {
result = teamsfx_api_1.err(new teamsfx_api_1.UserError(error_1.ExtensionErrors.ConcurrentTriggerTask, util.format(StringResources.vsc.handlers.concurrentTriggerTask, Array.from(runningTasks).join(",")), error_1.ExtensionSource));
yield processResult(eventName, result);
return result;
}
// 2. lock
runningTasks.add(stage);
// 3. check core not empty
const checkCoreRes = checkCoreNotEmpty();
if (checkCoreRes.isErr()) {
throw checkCoreRes.error;
}
const answers = new teamsfx_api_1.ConfigMap();
answers.set("stage", stage);
answers.set("platform", teamsfx_api_1.Platform.VSCode);
// 4. getQuestions
const qres = yield exports.core.getQuestions(stage, teamsfx_api_1.Platform.VSCode);
if (qres.isErr()) {
throw qres.error;
}
const vscenv = detectVsCodeEnv();
answers.set("vscenv", vscenv);
log_1.default.info(util.format(StringResources.vsc.handlers.vsCodeEnvironment, vscenv));
// 5. run question model
const node = qres.value;
if (node) {
const res = yield teamsfx_api_1.traverse(node, answers, vsc_ui_1.VS_CODE_UI, coreExeceutor);
if (res.type === teamsfx_api_1.InputResultType.error) {
throw res.error;
}
else if (res.type === teamsfx_api_1.InputResultType.cancel) {
throw new teamsfx_api_1.UserError(error_1.ExtensionErrors.UserCancel, StringResources.vsc.common.userCancel, error_1.ExtensionSource);
}
}
// 6. run task
if (stage === teamsfx_api_1.Stage.create)
result = yield exports.core.create(answers);
else if (stage === teamsfx_api_1.Stage.update)
result = yield exports.core.update(answers);
else if (stage === teamsfx_api_1.Stage.provision)
result = yield exports.core.provision(answers);
else if (stage === teamsfx_api_1.Stage.deploy)
result = yield exports.core.deploy(answers);
else if (stage === teamsfx_api_1.Stage.debug)
result = yield exports.core.localDebug(answers);
else if (stage === teamsfx_api_1.Stage.publish)
result = yield exports.core.publish(answers);
else {
throw new teamsfx_api_1.SystemError(error_1.ExtensionErrors.UnsupportedOperation, util.format(StringResources.vsc.handlers.operationNotSupport, stage), error_1.ExtensionSource);
}
}
catch (e) {
if ("name" in e && e.name === "DoProvisionFirst") {
runningTasks.delete(stage);
if (eventName) {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(eventName, {
[extTelemetryEvents_1.TelemetryProperty.Success]: extTelemetryEvents_1.TelemetrySuccess.No,
});
}
return yield provisionHandler();
}
result = wrapError(e);
}
// 7. unlock
runningTasks.delete(stage);
// 8. send telemetry and show error
yield processResult(eventName, result);
return result;
});
}
exports.runCommand = runCommand;
function detectVsCodeEnv() {
// extensionKind returns ExtensionKind.UI when running locally, so use this to detect remote
const extension = vscode.extensions.getExtension("Microsoft.teamsfx-extension");
if ((extension === null || extension === void 0 ? void 0 : extension.extensionKind) === vscode.ExtensionKind.Workspace) {
// running remotely
// Codespaces browser-based editor will return UIKind.Web for uiKind
if (vscode.env.uiKind === vscode.UIKind.Web) {
return teamsfx_api_1.VsCodeEnv.codespaceBrowser;
}
else if (vscode.env.remoteName === "codespaces") {
return teamsfx_api_1.VsCodeEnv.codespaceVsCode;
}
else {
return teamsfx_api_1.VsCodeEnv.remote;
}
}
else {
// running locally
return teamsfx_api_1.VsCodeEnv.local;
}
}
exports.detectVsCodeEnv = detectVsCodeEnv;
function runUserTask(func, eventName) {
return __awaiter(this, void 0, void 0, function* () {
let result = teamsfx_api_1.ok(null);
try {
// 1. check concurrent lock
if (runningTasks.size > 0) {
result = teamsfx_api_1.err(new teamsfx_api_1.UserError(error_1.ExtensionErrors.ConcurrentTriggerTask, util.format(StringResources.vsc.handlers.concurrentTriggerTask, Array.from(runningTasks).join(",")), error_1.ExtensionSource));
yield processResult(eventName, result);
return result;
}
// 2. lock
runningTasks.add(eventName);
// 3. check core not empty
const checkCoreRes = checkCoreNotEmpty();
if (checkCoreRes.isErr()) {
throw checkCoreRes.error;
}
const answers = new teamsfx_api_1.ConfigMap();
answers.set("task", eventName);
answers.set("platform", teamsfx_api_1.Platform.VSCode);
// 4. getQuestions
const qres = yield exports.core.getQuestionsForUserTask(func, teamsfx_api_1.Platform.VSCode);
if (qres.isErr()) {
throw qres.error;
}
// 5. run question model
const node = qres.value;
if (node) {
const res = yield teamsfx_api_1.traverse(node, answers, vsc_ui_1.VS_CODE_UI, coreExeceutor);
if (res.type === teamsfx_api_1.InputResultType.error && res.error) {
throw res.error;
}
else if (res.type === teamsfx_api_1.InputResultType.cancel) {
throw new teamsfx_api_1.UserError(error_1.ExtensionErrors.UserCancel, StringResources.vsc.common.userCancel, error_1.ExtensionSource);
}
}
// 6. run task
result = yield exports.core.executeUserTask(func, answers);
}
catch (e) {
result = wrapError(e);
}
// 7. unlock
runningTasks.delete(eventName);
// 8. send telemetry and show error
yield processResult(eventName, result);
return result;
});
}
//TODO workaround
function isLoginFaiureError(error) {
return !!error.message && error.message.includes("Cannot get user login information");
}
function processResult(eventName, result) {
return __awaiter(this, void 0, void 0, function* () {
if (result.isErr()) {
if (eventName) {
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(eventName, result.error);
}
const error = result.error;
if (teamsfx_core_1.isUserCancelError(error)) {
return;
}
if (isLoginFaiureError(error)) {
vscode_1.window.showErrorMessage(StringResources.vsc.handlers.loginFailed);
return;
}
showError(error);
}
else {
if (eventName) {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(eventName, {
[extTelemetryEvents_1.TelemetryProperty.Success]: extTelemetryEvents_1.TelemetrySuccess.Yes,
});
}
}
});
}
function wrapError(e) {
if (e instanceof teamsfx_api_1.UserError ||
e instanceof teamsfx_api_1.SystemError ||
(e.constructor &&
e.constructor.name &&
(e.constructor.name === "SystemError" || e.constructor.name === "UserError"))) {
return teamsfx_api_1.err(e);
}
return teamsfx_api_1.err(teamsfx_api_1.returnSystemError(e, error_1.ExtensionSource, error_1.ExtensionErrors.UnknwonError));
}
function checkCoreNotEmpty() {
if (!exports.core) {
return teamsfx_api_1.err(teamsfx_api_1.returnSystemError(new Error(StringResources.vsc.handlers.coreNotReady), error_1.ExtensionSource, error_1.ExtensionErrors.UnsupportedOperation));
}
return teamsfx_api_1.ok(null);
}
/**
* manually added customized command
*/
function updateAADHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.UpdateAadStart, getTriggerFromProperty(args));
const func = {
namespace: "fx-solution-azure/fx-resource-aad-app-for-teams",
method: "aadUpdatePermission",
};
return yield runUserTask(func, extTelemetryEvents_1.TelemetryEvent.UpdateAad);
});
}
exports.updateAADHandler = updateAADHandler;
function addCapabilityHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.AddCapStart, getTriggerFromProperty(args));
const func = {
namespace: "fx-solution-azure",
method: "addCapability",
};
return yield runUserTask(func, extTelemetryEvents_1.TelemetryEvent.AddCap);
});
}
exports.addCapabilityHandler = addCapabilityHandler;
/**
* check & install required dependencies during local debug when selected hosting type is Azure.
*/
function validateDependenciesHandler() {
return __awaiter(this, void 0, void 0, function* () {
const nodeChecker = new azureNodeChecker_1.AzureNodeChecker(vscodeAdapter_1.vscodeAdapter, vscodeLogger_1.vscodeLogger, vscodeTelemetry_1.vscodeTelemetry);
const dotnetChecker = new dotnetChecker_1.DotnetChecker(vscodeAdapter_1.vscodeAdapter, vscodeLogger_1.vscodeLogger, vscodeTelemetry_1.vscodeTelemetry);
const depsChecker = new checker_1.DepsChecker(vscodeLogger_1.vscodeLogger, vscodeAdapter_1.vscodeAdapter, [nodeChecker, dotnetChecker]);
yield validateDependenciesCore(depsChecker);
});
}
exports.validateDependenciesHandler = validateDependenciesHandler;
/**
* check & install required dependencies during local debug when selected hosting type is SPFx.
*/
function validateSpfxDependenciesHandler() {
return __awaiter(this, void 0, void 0, function* () {
const nodeChecker = new spfxNodeChecker_1.SPFxNodeChecker(vscodeAdapter_1.vscodeAdapter, vscodeLogger_1.vscodeLogger, vscodeTelemetry_1.vscodeTelemetry);
const depsChecker = new checker_1.DepsChecker(vscodeLogger_1.vscodeLogger, vscodeAdapter_1.vscodeAdapter, [nodeChecker]);
yield validateDependenciesCore(depsChecker);
});
}
exports.validateSpfxDependenciesHandler = validateSpfxDependenciesHandler;
function validateDependenciesCore(depsChecker) {
return __awaiter(this, void 0, void 0, function* () {
const shouldContinue = yield depsChecker.resolve();
if (!shouldContinue) {
yield vscode_1.debug.stopDebugging();
// TODO: better mechanism to stop the tasks and debug session.
throw new Error("debug stopped.");
}
});
}
/**
* install functions binding before launch local debug
*/
function backendExtensionsInstallHandler() {
return __awaiter(this, void 0, void 0, function* () {
if (vscode_1.workspace.workspaceFolders && vscode_1.workspace.workspaceFolders.length > 0) {
const workspaceFolder = vscode_1.workspace.workspaceFolders[0];
const backendRoot = yield commonUtils.getProjectRoot(workspaceFolder.uri.fsPath, constants.backendFolderName);
if (backendRoot) {
const dotnetChecker = new dotnetChecker_1.DotnetChecker(vscodeAdapter_1.vscodeAdapter, vscodeLogger_1.vscodeLogger, vscodeTelemetry_1.vscodeTelemetry);
const backendExtensionsInstaller = new backendExtensionsInstall_1.BackendExtensionsInstaller(dotnetChecker, vscodeLogger_1.vscodeLogger);
try {
yield backendExtensionsInstaller.install(backendRoot);
}
catch (error) {
yield checker_1.DepsChecker.handleErrorWithDisplay(error, vscodeAdapter_1.vscodeAdapter);
throw error;
}
}
}
});
}
exports.backendExtensionsInstallHandler = backendExtensionsInstallHandler;
/**
* call localDebug on core
*/
function preDebugCheckHandler() {
return __awaiter(this, void 0, void 0, function* () {
try {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.DebugPreCheck);
}
catch (_a) {
// ignore telemetry error
}
let result = teamsfx_api_1.ok(null);
result = yield runCommand(teamsfx_api_1.Stage.debug);
if (result.isErr()) {
try {
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.DebugPreCheck, result.error);
}
finally {
// ignore telemetry error
teamsfxTaskHandler_1.terminateAllRunningTeamsfxTasks();
throw result.error;
}
}
const portsInUse = yield commonUtils.getPortsInUse();
if (portsInUse.length > 0) {
let message;
if (portsInUse.length > 1) {
message = util.format(StringResources.vsc.localDebug.portsAlreadyInUse, portsInUse.join(", "));
}
else {
message = util.format(StringResources.vsc.localDebug.portAlreadyInUse, portsInUse[0]);
}
const error = new teamsfx_api_1.UserError(error_1.ExtensionErrors.PortAlreadyInUse, message, error_1.ExtensionSource);
try {
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.DebugPreCheck, error);
}
finally {
// ignore telemetry error
vscode_1.window.showErrorMessage(message);
teamsfxTaskHandler_1.terminateAllRunningTeamsfxTasks();
throw error;
}
}
});
}
exports.preDebugCheckHandler = preDebugCheckHandler;
function openDocumentHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.Documentation, getTriggerFromProperty(args));
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://aka.ms/build-first-app"));
});
}
exports.openDocumentHandler = openDocumentHandler;
function openWelcomeHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.QuickStart, getTriggerFromProperty(args));
webviewPanel_1.WebviewPanel.createOrShow(extensionVariables_1.ext.context.extensionPath, PanelType_1.PanelType.QuickStart);
});
}
exports.openWelcomeHandler = openWelcomeHandler;
function getTriggerFromProperty(args) {
const isFromTreeView = args && args.toString() === "TreeView";
return {
[extTelemetryEvents_1.TelemetryProperty.TriggerFrom]: isFromTreeView
? extTelemetryEvents_1.TelemetryTiggerFrom.TreeView
: extTelemetryEvents_1.TelemetryTiggerFrom.CommandPalette,
};
}
function openMarkdownHandler() {
return __awaiter(this, void 0, void 0, function* () {
const afterScaffold = extensionVariables_1.ext.context.globalState.get("openReadme", false);
if (afterScaffold && vscode_1.workspace.workspaceFolders && vscode_1.workspace.workspaceFolders.length > 0) {
extensionVariables_1.ext.context.globalState.update("openReadme", false);
const workspaceFolder = vscode_1.workspace.workspaceFolders[0];
const workspacePath = workspaceFolder.uri.fsPath;
let targetFolder;
if (yield commonUtils_1.isSPFxProject(workspacePath)) {
targetFolder = `${workspacePath}/SPFx`;
}
else {
const tabFolder = yield commonUtils.getProjectRoot(workspacePath, constants.frontendFolderName);
const botFolder = yield commonUtils.getProjectRoot(workspacePath, constants.botFolderName);
if (tabFolder && botFolder) {
targetFolder = workspacePath;
}
else if (tabFolder) {
targetFolder = tabFolder;
}
else {
targetFolder = botFolder;
}
}
const uri = vscode_1.Uri.file(`${targetFolder}/README.md`);
vscode_1.workspace
.openTextDocument(uri)
.then((document) => {
vscode_1.window.showTextDocument(document);
})
.then(() => {
const PreviewMarkdownCommand = "markdown.showPreviewToSide";
vscode_1.commands.executeCommand(PreviewMarkdownCommand, uri);
});
}
});
}
function openSamplesHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.Samples, getTriggerFromProperty(args));
webviewPanel_1.WebviewPanel.createOrShow(extensionVariables_1.ext.context.extensionPath, PanelType_1.PanelType.SampleGallery);
});
}
exports.openSamplesHandler = openSamplesHandler;
function openAppManagement(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ManageTeamsApp, getTriggerFromProperty(args));
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://dev.teams.microsoft.com/home"));
});
}
exports.openAppManagement = openAppManagement;
function openBotManagement(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ManageTeamsBot, getTriggerFromProperty(args));
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://dev.teams.microsoft.com/bots"));
});
}
exports.openBotManagement = openBotManagement;
function openReportIssues(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.ReportIssues, getTriggerFromProperty(args));
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://github.com/OfficeDev/TeamsFx/issues"));
});
}
exports.openReportIssues = openReportIssues;
function openManifestHandler(args) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.OpenManifestEditorStart, getTriggerFromProperty(args));
if (vscode_1.workspace.workspaceFolders && vscode_1.workspace.workspaceFolders.length > 0) {
const workspaceFolder = vscode_1.workspace.workspaceFolders[0];
const configRoot = yield commonUtils.getProjectRoot(workspaceFolder.uri.fsPath, `.${teamsfx_api_1.ConfigFolderName}`);
const manifestFile = `${configRoot}/${constants.manifestFileName}`;
if (fs.existsSync(manifestFile)) {
vscode_1.workspace.openTextDocument(manifestFile).then((document) => {
vscode_1.window.showTextDocument(document);
});
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.OpenManifestEditor, {
[extTelemetryEvents_1.TelemetryProperty.Success]: extTelemetryEvents_1.TelemetrySuccess.Yes,
});
return teamsfx_api_1.ok(null);
}
else {
const FxError = {
name: "FileNotFound",
source: error_1.ExtensionSource,
message: util.format(StringResources.vsc.handlers.fileNotFound, manifestFile),
timestamp: new Date(),
};
showError(FxError);
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.OpenManifestEditor, FxError);
return teamsfx_api_1.err(FxError);
}
}
else {
const FxError = {
name: "NoWorkspace",
source: error_1.ExtensionSource,
message: StringResources.vsc.handlers.noOpenWorkspace,
timestamp: new Date(),
};
showError(FxError);
extTelemetry_1.ExtTelemetry.sendTelemetryErrorEvent(extTelemetryEvents_1.TelemetryEvent.OpenManifestEditor, FxError);
return teamsfx_api_1.err(FxError);
}
});
}
exports.openManifestHandler = openManifestHandler;
function openM365AccountHandler() {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.OpenM365Portal);
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://admin.microsoft.com/Adminportal/"));
});
}
exports.openM365AccountHandler = openM365AccountHandler;
function openAzureAccountHandler() {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.OpenAzurePortal);
return vscode_1.env.openExternal(vscode_1.Uri.parse("https://portal.azure.com/"));
});
}
exports.openAzureAccountHandler = openAzureAccountHandler;
function cmdHdlLoadTreeView(context) {
return __awaiter(this, void 0, void 0, function* () {
const disposables = commandsTreeViewProvider_1.default.registerTreeViews();
context.subscriptions.push(...disposables);
// Register SignOut tree view command
vscode_1.commands.registerCommand("fx-extension.signOut", (node) => __awaiter(this, void 0, void 0, function* () {
try {
switch (node.contextValue) {
case "signedinM365": {
signOutM365(true);
break;
}
case "signedinAzure": {
signOutAzure(true);
break;
}
}
}
catch (e) {
showError(e);
}
}));
vscode_1.commands.registerCommand("fx-extension.signInGuideline", (node) => __awaiter(this, void 0, void 0, function* () {
// TODO: update the link when documentation is ready
switch (node.contextValue) {
case "signinM365": {
yield vscode_1.env.openExternal(vscode_1.Uri.parse("https://www.office.com/"));
break;
}
case "signinAzure": {
yield vscode_1.env.openExternal(vscode_1.Uri.parse("https://portal.azure.com/"));
break;
}
}
}));
});
}
exports.cmdHdlLoadTreeView = cmdHdlLoadTreeView;
function cmdHdlDisposeTreeView() {
commandsTreeViewProvider_1.default.dispose();
}
exports.cmdHdlDisposeTreeView = cmdHdlDisposeTreeView;
function showError(e) {
return __awaiter(this, void 0, void 0, function* () {
log_1.default.error(`code:${e.source}.${e.name}, message: ${e.message}, stack: ${e.stack}`);
const errorCode = `${e.source}.${e.name}`;
if (teamsfx_core_1.isUserCancelError(e)) {
return;
}
else if ("helpLink" in e && e.helpLink && typeof e.helpLink != "undefined") {
const help = {
title: StringResources.vsc.handlers.getHelp,
run: () => __awaiter(this, void 0, void 0, function* () {
vscode_1.commands.executeCommand("vscode.open", vscode_1.Uri.parse(`${e.helpLink}#${e.source}${e.name}`));
}),
};
const button = yield vscode_1.window.showErrorMessage(`[${errorCode}]: ${e.message}`, help);
if (button)
yield button.run();
}
else if ("issueLink" in e && e.issueLink && typeof e.issueLink != "undefined") {
const path = e.issueLink.replace(/\/$/, "") + "?";
const param = `title=new+bug+report: ${errorCode}&body=${e.message}\n\n${e.stack}`;
const issue = {
title: StringResources.vsc.handlers.reportIssue,
run: () => __awaiter(this, void 0, void 0, function* () {
vscode_1.commands.executeCommand("vscode.open", vscode_1.Uri.parse(`${path}${param}`));
}),
};
const button = yield vscode_1.window.showErrorMessage(`[${errorCode}]: ${e.message}`, issue);
if (button)
yield button.run();
}
else {
yield vscode_1.window.showErrorMessage(`[${errorCode}]: ${e.message}`);
}
});
}
exports.showError = showError;
function cmpAccountsHandler() {
return __awaiter(this, void 0, void 0, function* () {
const signInAzureOption = {
id: "signInAzure",
label: "Sign in to Azure",
function: () => signInAzure(),
};
const signOutAzureOption = {
id: "signOutAzure",
label: "Sign out of Azure: ",
function: () => signOutAzure(false),
};
const signInM365Option = {
id: "signinM365",
label: "Sign in to M365",
function: () => signInM365(),
};
const signOutM365Option = {
id: "signOutM365",
label: "Sign out of M365: ",
function: () => signOutM365(false),
};
//TODO: hide subscription list until core or api expose the get subscription list API
// let selectSubscriptionOption: VscQuickPickItem = {
// id: "selectSubscription",
// label: "Specify an Azure Subscription",
// function: () => selectSubscription(),
// detail: "4 subscriptions discovered"
// };
const quickPick = vscode_1.window.createQuickPick();
const quickItemOptionArray = [];
const m365Account = yield appStudioLogin_1.default.getStatus();
if (m365Account.status === "SignedIn") {
const accountInfo = m365Account.accountInfo;
const email = accountInfo.upn ? accountInfo.upn : undefined;
if (email !== undefined) {
signOutM365Option.label = signOutM365Option.label.concat(email);
}
quickItemOptionArray.push(signOutM365Option);
}
else {
quickItemOptionArray.push(signInM365Option);
}
const azureAccount = yield azureLogin_1.default.getStatus();
if (azureAccount.status === "SignedIn") {
const accountInfo = azureAccount.accountInfo;
const email = accountInfo.upn ? accountInfo.upn : undefined;
if (email !== undefined) {
signOutAzureOption.label = signOutAzureOption.label.concat(email);
}
quickItemOptionArray.push(signOutAzureOption);
//quickItemOptionArray.push(selectSubscriptionOption);
}
else {
quickItemOptionArray.push(signInAzureOption);
}
quickPick.items = quickItemOptionArray;
quickPick.onDidChangeSelection((selection) => {
if (selection[0]) {
selection[0].function().catch(console.error);
}
});
quickPick.onDidHide(() => quickPick.dispose());
quickPick.show();
});
}
exports.cmpAccountsHandler = cmpAccountsHandler;
function signOutAzure(isFromTreeView) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.SignOutStart, {
[extTelemetryEvents_1.TelemetryProperty.TriggerFrom]: isFromTreeView
? extTelemetryEvents_1.TelemetryTiggerFrom.TreeView
: extTelemetryEvents_1.TelemetryTiggerFrom.CommandPalette,
[extTelemetryEvents_1.TelemetryProperty.AccountType]: extTelemetryEvents_1.AccountType.Azure,
});
const result = yield azureLogin_1.default.signout();
if (result) {
yield commandsTreeViewProvider_1.default.getTreeView("teamsfx-accounts").refresh([
{
commandId: "fx-extension.signinAzure",
label: StringResources.vsc.handlers.signInAzure,
contextValue: "signinAzure",
},
]);
yield commandsTreeViewProvider_1.default.getTreeView("teamsfx-accounts").remove([
{
commandId: "fx-extension.selectSubscription",
label: "",
parent: "fx-extension.signinAzure",
},
]);
}
});
}
exports.signOutAzure = signOutAzure;
function signOutM365(isFromTreeView) {
return __awaiter(this, void 0, void 0, function* () {
extTelemetry_1.ExtTelemetry.sendTelemetryEvent(extTelemetryEvents_1.TelemetryEvent.SignOutStart, {
[extTelemetryEvents_1.TelemetryProperty.TriggerFrom]: isFromTreeView
? extTelemetryEvents_1.TelemetryTiggerFrom.TreeView
: extTelemetryEvents_1.TelemetryTiggerFrom.CommandPalette,
[extTelemetryEvents_1.TelemetryProperty.AccountType]: extTelemetryEvents_1.AccountType.M365,
});
let appstudioLogin = appStudioLogin_1.default;
const vscodeEnv = detectVsCodeEnv();
if (vscodeEnv === teamsfx_api_1.VsCodeEnv.codespaceBrowser || vscodeEnv === teamsfx_api_1.VsCodeEnv.codespaceVsCode) {
appstudioLogin = appStudioCodeSpaceLogin_1.default;
}
const result = yield appstudioLogin.signout();
if (result) {
yield commandsTreeViewProvider_1.default.getTreeView("teamsfx-accounts").refresh([
{
commandId: "fx-extension.signinM365",
label: StringResources.vsc.handlers.signIn365,
contextValue: "signinM365",
},
]);
}
});
}
exports.signOutM365 = signOutM365;
function signInAzure() {
return __awaiter(this, void 0, void 0, function* () {
vscode.commands.executeCommand("fx-extension.signinAzure");
});
}
exports.signInAzure = signInAzure;
function signInM365() {
return __awaiter(this, void 0, void 0, function* () {
vscode.commands.executeCommand("fx-extension.signinM365");
});
}
exports.signInM365 = signInM365;
function selectSubscription() {
return __awaiter(this, void 0, void 0, function* () {
vscode.commands.executeCommand("fx-extension.specifySubscription");
});
}
exports.selectSubscription = selectSubscription;
//# sourceMappingURL=handlers.js.map