diff --git a/package-lock.json b/package-lock.json index 0bd1b1aa..23940c58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@microsoft/vscode-azext-azureutils": "^3.5.2", "@microsoft/vscode-azext-github": "^1.0.7", "@microsoft/vscode-azext-utils": "^3.5.1", - "@microsoft/vscode-azureresources-api": "^2.6.3", + "@microsoft/vscode-azureresources-api": "file:../vscode-azureresourcegroups/api/microsoft-vscode-azureresources-api-3.0.0.tgz", "@vscode/codicons": "0.0.38", "buffer": "^6.0.3", "dayjs": "^1.11.3", @@ -2728,6 +2728,15 @@ "@azure/ms-rest-azure-env": "^2.0.0" } }, + "node_modules/@microsoft/vscode-azext-utils/node_modules/@microsoft/vscode-azureresources-api": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.6.3.tgz", + "integrity": "sha512-uwFHLc9fsbuBPKC/WOU+p5JMj9VyNyU1k+3T1uFp00l4OMmazqBqiJYKao6jc/d525hy9FW6EzniGPHdocKApA==", + "license": "MIT", + "peerDependencies": { + "@azure/ms-rest-azure-env": "^2.0.0" + } + }, "node_modules/@microsoft/vscode-azext-utils/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -2749,9 +2758,13 @@ } }, "node_modules/@microsoft/vscode-azureresources-api": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.6.3.tgz", - "integrity": "sha512-uwFHLc9fsbuBPKC/WOU+p5JMj9VyNyU1k+3T1uFp00l4OMmazqBqiJYKao6jc/d525hy9FW6EzniGPHdocKApA==", + "version": "3.0.0", + "resolved": "file:../vscode-azureresourcegroups/api/microsoft-vscode-azureresources-api-3.0.0.tgz", + "integrity": "sha512-1lUCGvYIUDJHv4o+sqkak203mSmLoKzFR1ETBHLhZJ3dt5B9DJ/Z4IIo0Lg3bvOY0yZXm/HNLNvPkeRtfH05Zg==", + "license": "MIT", + "engines": { + "vscode": "^1.105.0" + }, "peerDependencies": { "@azure/ms-rest-azure-env": "^2.0.0" } diff --git a/package.json b/package.json index 3de01409..d57ae9b2 100644 --- a/package.json +++ b/package.json @@ -865,7 +865,7 @@ "@microsoft/vscode-azext-azureutils": "^3.5.2", "@microsoft/vscode-azext-github": "^1.0.7", "@microsoft/vscode-azext-utils": "^3.5.1", - "@microsoft/vscode-azureresources-api": "^2.6.3", + "@microsoft/vscode-azureresources-api": "file:../vscode-azureresourcegroups/api/microsoft-vscode-azureresources-api-3.0.0.tgz", "@vscode/codicons": "0.0.38", "buffer": "^6.0.3", "dayjs": "^1.11.3", diff --git a/src/commands/api/createContainerAppsApiProvider.ts b/src/commands/api/createContainerAppsApiProvider.ts new file mode 100644 index 00000000..41f56803 --- /dev/null +++ b/src/commands/api/createContainerAppsApiProvider.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Microsoft Corporation. All rights reserved. +* Licensed under the MIT License. See License.md in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import { callWithTelemetryAndErrorHandling, createApiProvider, maskUserInfo, type apiUtils, type IActionContext } from "@microsoft/vscode-azext-utils"; +import { prepareAzureResourcesApiRequest, type AzureResourcesApiRequestContext, type AzureResourcesApiRequestError } from "@microsoft/vscode-azureresources-api"; +import { ext } from "../../extensionVariables"; +import { localize } from "../../utils/localize"; +import { deployImageApi } from "./deployImageApi"; +import { deployWorkspaceProjectApi } from "./deployWorkspaceProjectApi"; +import type * as api from "./vscode-azurecontainerapps.api"; + +export function createContainerAppsApiProvider(registerBranchResources: AzureResourcesApiRequestContext["onDidReceiveAzureResourcesApis"]): apiUtils.AzureExtensionApiProvider { + const context: AzureResourcesApiRequestContext = { + azureResourcesApiVersions: ['^2.0.0'], + clientExtensionId: ext.context.extension.id, + onDidReceiveAzureResourcesApis: registerBranchResources, + onApiRequestError: async (error: AzureResourcesApiRequestError) => { + await callWithTelemetryAndErrorHandling('hostApiRequestFailed', (actionContext: IActionContext) => { + actionContext.telemetry.properties.hostApiRequestErrorCode = error.code; + actionContext.telemetry.properties.hostApiRequestError = maskUserInfo(error.message, []); + ext.outputChannel.appendLog(localize('apiRequestError', 'Error: Failed to connect extension to the Azure Resources host.')); + ext.outputChannel.appendLog(`code: ${error.code}, message: ${error.message}`); + }); + }, + }; + + const containerAppsApi: api.AzureContainerAppsExtensionApi = { + apiVersion: '1.0.0', + deployImage: deployImageApi, + deployWorkspaceProject: deployWorkspaceProjectApi, + }; + + const { clientApi, requestResourcesApis } = prepareAzureResourcesApiRequest(context, containerAppsApi); + requestResourcesApis(); + return createApiProvider([clientApi]); +} diff --git a/src/commands/api/getAzureContainerAppsApiProvider.ts b/src/commands/api/getAzureContainerAppsApiProvider.ts deleted file mode 100644 index 055cd5cd..00000000 --- a/src/commands/api/getAzureContainerAppsApiProvider.ts +++ /dev/null @@ -1,17 +0,0 @@ -/*--------------------------------------------------------------------------------------------- -* Copyright (c) Microsoft Corporation. All rights reserved. -* Licensed under the MIT License. See License.md in the project root for license information. -*--------------------------------------------------------------------------------------------*/ - -import { createApiProvider, type apiUtils } from "@microsoft/vscode-azext-utils"; -import { deployImageApi } from "./deployImageApi"; -import { deployWorkspaceProjectApi } from "./deployWorkspaceProjectApi"; -import type * as api from "./vscode-azurecontainerapps.api"; - -export function getAzureContainerAppsApiProvider(): apiUtils.AzureExtensionApiProvider { - return createApiProvider([{ - apiVersion: '1.0.0', - deployImage: deployImageApi, - deployWorkspaceProject: deployWorkspaceProjectApi, - }]); -} diff --git a/src/commands/api/vscode-azurecontainerapps.api.d.ts b/src/commands/api/vscode-azurecontainerapps.api.d.ts index 28b950f3..fce8f617 100644 --- a/src/commands/api/vscode-azurecontainerapps.api.d.ts +++ b/src/commands/api/vscode-azurecontainerapps.api.d.ts @@ -3,7 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export interface AzureContainerAppsExtensionApi { +import { type AzureExtensionApi } from "@microsoft/vscode-azureresources-api"; + +export interface AzureContainerAppsExtensionApi extends AzureExtensionApi { apiVersion: string; deployImage(options: DeployImageToAcaOptionsContract): Promise; deployWorkspaceProject(options: DeployWorkspaceProjectOptionsContract): Promise; diff --git a/src/extension.ts b/src/extension.ts index 8fe84ce0..73019c22 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,14 +7,15 @@ import { registerAzureUtilsExtensionVariables } from '@microsoft/vscode-azext-azureutils'; import { registerGitHubExtensionVariables } from '@microsoft/vscode-azext-github'; -import { TreeElementStateManager, callWithTelemetryAndErrorHandling, createAzExtOutputChannel, createExperimentationService, registerUIExtensionVariables, type IActionContext, type apiUtils } from '@microsoft/vscode-azext-utils'; -import { AzExtResourceType, getAzureResourcesExtensionApi } from '@microsoft/vscode-azureresources-api'; +import { TreeElementStateManager, callWithTelemetryAndErrorHandling, createApiProvider, createAzExtOutputChannel, createExperimentationService, registerUIExtensionVariables, type IActionContext, type apiUtils } from '@microsoft/vscode-azext-utils'; +import { AzExtResourceType, type AzureResourcesExtensionApi } from '@microsoft/vscode-azureresources-api'; import * as vscode from 'vscode'; -import { getAzureContainerAppsApiProvider } from './commands/api/getAzureContainerAppsApiProvider'; +import { createContainerAppsApiProvider } from './commands/api/createContainerAppsApiProvider'; import { registerCommands } from './commands/registerCommands'; import { RevisionDraftFileSystem } from './commands/revisionDraft/RevisionDraftFileSystem'; import { ext } from './extensionVariables'; import { ContainerAppsBranchDataProvider } from './tree/ContainerAppsBranchDataProvider'; +import { localize } from './utils/localize'; export async function activate(context: vscode.ExtensionContext, perfStats: { loadStartTime: number; loadEndTime: number }, ignoreBundle?: boolean): Promise { // the entry point for vscode.dev is this activate, not main.js, so we need to instantiate perfStats here @@ -29,7 +30,8 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo registerAzureUtilsExtensionVariables(ext); registerGitHubExtensionVariables(ext); - await callWithTelemetryAndErrorHandling('containerApps.activate', async (activateContext: IActionContext) => { + return await callWithTelemetryAndErrorHandling('containerApps.activate', async (activateContext: IActionContext) => { + activateContext.errorHandling.rethrow = true; activateContext.telemetry.properties.isActivationEvent = 'true'; activateContext.telemetry.measurements.mainFileLoad = (perfStats.loadEndTime - perfStats.loadStartTime) / 1000; @@ -40,12 +42,25 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo context.subscriptions.push(vscode.workspace.registerFileSystemProvider(RevisionDraftFileSystem.scheme, ext.revisionDraftFileSystem)); ext.state = new TreeElementStateManager(); - ext.rgApiV2 = await getAzureResourcesExtensionApi(context, '2.0.0'); ext.branchDataProvider = new ContainerAppsBranchDataProvider(); - ext.rgApiV2.resources.registerAzureResourceBranchDataProvider(AzExtResourceType.ContainerAppsEnvironment, ext.branchDataProvider); - }); - return getAzureContainerAppsApiProvider(); + const registerBranchResources = async (azureResourcesApis: (AzureResourcesExtensionApi | undefined)[]) => { + await callWithTelemetryAndErrorHandling('hostApiRequestSucceeded', (actionContext: IActionContext) => { + actionContext.errorHandling.rethrow = true; + + const [rgApiV2] = azureResourcesApis; + if (!rgApiV2 || !rgApiV2.apiVersion.match(/^2\./)) { + throw new Error(localize('noMatchingApi', 'Failed to find a matching Azure Resources API for version "{0}".', '^2.0.0')); + } + + ext.rgApiV2 = rgApiV2; + ext.rgApiV2.resources.registerAzureResourceBranchDataProvider(AzExtResourceType.ContainerAppsEnvironment, ext.branchDataProvider); + }); + }; + + return createContainerAppsApiProvider(registerBranchResources); + + }) ?? createApiProvider([]); } // eslint-disable-next-line @typescript-eslint/no-empty-function