From c22d9667158548b9ca6149413abf63a23166f1c6 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:18:49 -0800 Subject: [PATCH 01/25] WIP: Domain name changes --- .../IAppServiceWizardContext.ts | 13 +++++ .../SiteDomainNameLabelScopeStep.ts | 48 +++++++++++++++ .../src/createAppService/SiteNameStep.ts | 58 +++++++++++++++++-- appservice/src/index.ts | 16 ++--- 4 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts diff --git a/appservice/src/createAppService/IAppServiceWizardContext.ts b/appservice/src/createAppService/IAppServiceWizardContext.ts index 4d4294f5fb..88715a8ce5 100644 --- a/appservice/src/createAppService/IAppServiceWizardContext.ts +++ b/appservice/src/createAppService/IAppServiceWizardContext.ts @@ -8,6 +8,7 @@ import type { AppServicePlan, Site, SkuDescription } from '@azure/arm-appservice import type { Workspace } from '@azure/arm-operationalinsights'; import { IResourceGroupWizardContext, IStorageAccountWizardContext } from '@microsoft/vscode-azext-azureutils'; import { AppKind, WebsiteOS } from './AppKind'; +import { DomainNameLabelScope } from './SiteDomainNameLabelScopeStep'; export interface IAppServiceWizardContext extends IResourceGroupWizardContext, IStorageAccountWizardContext { newSiteKind: AppKind; @@ -30,6 +31,18 @@ export interface IAppServiceWizardContext extends IResourceGroupWizardContext, I */ newSiteName?: string; + /** + * The domain name label scope for the new site + * This will be defined after `SiteDomainLabelScopeStep.prompt` occurs. + */ + newSiteDomainNameLabelScope?: DomainNameLabelScope; + + /** + * Specifies whether or not to display DomainNameLabelScope.ResourceGroup as a pick option. + * This will be defined during `SiteDomainLabelScopeStep.prompt` + */ + omitResourceGroupDomainNameScope?: boolean; + /** * The App Service plan to use. * If an existing plan is picked, this value will be defined after `AppServicePlanListStep.prompt` occurs diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts new file mode 100644 index 0000000000..81c473eed8 --- /dev/null +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -0,0 +1,48 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { AzureWizardPromptStep, IAzureQuickPickItem } from '@microsoft/vscode-azext-utils'; +import * as vscode from 'vscode'; +import { IAppServiceWizardContext } from './IAppServiceWizardContext'; + +export enum DomainNameLabelScope { + ResourceGroup = 'ResourceGroupReuse', + Subscription = 'SubscriptionReuse', + Tenant = 'TenantReuse', + Global = 'NoReuse', +} + +export class SiteDomainNameLabelScopeStep extends AzureWizardPromptStep { + public async prompt(context: T): Promise { + const picks: IAzureQuickPickItem[] = [ + { label: vscode.l10n.t('Tenant'), description: vscode.l10n.t('(recommended)'), data: DomainNameLabelScope.Tenant }, + { label: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, + { label: vscode.l10n.t('Subscription'), data: DomainNameLabelScope.Subscription }, + ]; + + if (!context.omitResourceGroupDomainNameScope) { + picks.push({ label: vscode.l10n.t('Resource group'), data: DomainNameLabelScope.ResourceGroup }); + } + + let result: DomainNameLabelScope | undefined; + do { + result = (await context.ui.showQuickPick(picks, { + placeHolder: vscode.l10n.t('Select the uniqueness level for your domain name'), + suppressPersistence: true, + })).data; + + if (!result) { + // Todo: Open learn more link + } + } while (!result); + + context.telemetry.properties.siteDomainNameLabelScope = result; + context.newSiteDomainNameLabelScope = result; + } + + public shouldPrompt(context: T): boolean { + return !context.newSiteDomainNameLabelScope; + } +} diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 46393782c9..36e1dbb796 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import type { ResourceNameAvailability, WebSiteManagementClient } from '@azure/arm-appservice'; -import { ResourceGroupListStep, StorageAccountListStep, resourceGroupNamingRules, storageAccountNamingRules } from '@microsoft/vscode-azext-azureutils'; -import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules } from '@microsoft/vscode-azext-utils'; +import { createHttpHeaders, createPipelineRequest } from '@azure/core-rest-pipeline'; +import { AzExtLocation, AzExtPipelineResponse, AzExtRequestPrepareOptions, LocationListStep, ResourceGroupListStep, StorageAccountListStep, createGenericClient, resourceGroupNamingRules, storageAccountNamingRules } from '@microsoft/vscode-azext-azureutils'; +import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules, nonNullValueAndProp } from '@microsoft/vscode-azext-utils'; import * as vscode from 'vscode'; import { createWebSiteClient } from '../utils/azureClients'; import { appInsightsNamingRules } from './AppInsightsListStep'; @@ -13,6 +14,7 @@ import { AppKind } from './AppKind'; import { AppServicePlanListStep } from './AppServicePlanListStep'; import { appServicePlanNamingRules } from './AppServicePlanNameStep'; import { IAppServiceWizardContext } from './IAppServiceWizardContext'; +import { DomainNameLabelScope } from './SiteDomainNameLabelScopeStep'; interface SiteNameStepWizardContext extends IAppServiceWizardContext { ui: IAzureAgentInput; @@ -56,7 +58,7 @@ export class SiteNameStep extends AzureNameStep { } else if (context.newSiteKind?.includes(AppKind.workflowapp)) { prompt = vscode.l10n.t('Enter a globally unique name for the new logic app.'); } else { - prompt = vscode.l10n.t('Enter a globally unique name for the new web app.'); + prompt = vscode.l10n.t('Enter a name for the new web app.'); } const agentMetadata = this._siteFor === ("functionApp") || this._siteFor === ("containerizedFunctionApp") ? @@ -71,7 +73,7 @@ export class SiteNameStep extends AzureNameStep { prompt, placeHolder, validateInput: (name: string): string | undefined => this.validateSiteName(name), - asyncValidationTask: async (name: string): Promise => await this.asyncValidateSiteName(client, name), + asyncValidationTask: async (name: string): Promise => await this.asyncValidateSiteName(context, client, name), agentMetadata: agentMetadata }; @@ -122,7 +124,53 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - private async asyncValidateSiteName(client: WebSiteManagementClient, name: string): Promise { + private async asyncValidateSiteName(context: IAppServiceWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { + return context.newSiteDomainNameLabelScope && context.newSiteDomainNameLabelScope !== DomainNameLabelScope.Global ? + await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName) : + await this.asyncValidateSiteNameByGlobalScope(sdkClient, name); + } + + private async asyncValidateSiteNameByDomainScope(context: IAppServiceWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { + if (!LocationListStep.hasLocation(context)) { + throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with non-global domain scope.')); + } + if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { + throw new Error(vscode.l10n.t('Internal Error: A resource group name is required when validating a site name with resource group level domain scope.')); + } + + const apiVersion: string = '2024-04-01'; + const location: AzExtLocation = await LocationListStep.getLocation(context); + const authToken: string = nonNullValueAndProp((await context.credentials.getToken() as { token?: string }), 'token'); + + // Todo: Can replace with call to SDK once updated version is out + const options: AzExtRequestPrepareOptions = { + url: `https://management.azure.com/subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, + method: 'POST', + headers: createHttpHeaders({ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${authToken}`, + }), + body: JSON.stringify({ + name: siteName, + type: 'Site', + autoGeneratedDomainNameLabelScope: domainNameScope, + resourceGroupName: domainNameScope === DomainNameLabelScope.ResourceGroup ? resourceGroupName : undefined, + }), + }; + + const client = await createGenericClient(context, undefined); + const pipelineResponse = await client.sendRequest(createPipelineRequest(options)) as AzExtPipelineResponse; + + const checkNameResponse = pipelineResponse.parsedBody as { + hostName?: string; + message?: string; + nameAvailable?: boolean; + reason?: string; + }; + return !checkNameResponse.nameAvailable ? checkNameResponse.message : undefined; + } + + private async asyncValidateSiteNameByGlobalScope(client: WebSiteManagementClient, name: string): Promise { const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); if (!nameAvailability.nameAvailable) { return nameAvailability.message; diff --git a/appservice/src/index.ts b/appservice/src/index.ts index 2d23220002..d051f4506f 100644 --- a/appservice/src/index.ts +++ b/appservice/src/index.ts @@ -3,9 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export * from './KuduModels'; -export * from './SiteClient'; -export * from './TunnelProxy'; export * from './confirmOverwriteSettings'; export * from './createAppService/AppInsightsCreateStep'; export * from './createAppService/AppInsightsListStep'; @@ -17,23 +14,27 @@ export * from './createAppService/AppServicePlanSkuStep'; export * from './createAppService/CustomLocationListStep'; export * from './createAppService/IAppServiceWizardContext'; export * from './createAppService/LogAnalyticsCreateStep'; +export * from './createAppService/setLocationsTask'; +export * from './createAppService/SiteDomainNameLabelScopeStep'; export * from './createAppService/SiteNameStep'; export * from './createAppService/SiteOSStep'; -export * from './createAppService/setLocationsTask'; export * from './createSlot'; export * from './deleteSite/DeleteLastServicePlanStep'; export * from './deleteSite/DeleteSiteStep'; export * from './deleteSite/IDeleteSiteWizardContext'; -export * from './deploy/IDeployContext'; export * from './deploy/deploy'; export * from './deploy/getDeployFsPath'; export * from './deploy/getDeployNode'; +export * from './deploy/IDeployContext'; export * from './deploy/localGitDeploy'; -export { IPreDeployTaskResult, handleFailedPreDeployTask, runPreDeployTask, tryRunPreDeployTask } from './deploy/runDeployTask'; +export { handleFailedPreDeployTask, IPreDeployTaskResult, runPreDeployTask, tryRunPreDeployTask } from './deploy/runDeployTask'; export * from './deploy/showDeployConfirmation'; export { disconnectRepo } from './disconnectRepo'; export * from './editScmType'; export { registerAppServiceExtensionVariables } from './extensionVariables'; +export * from './KuduModels'; +export * from './SiteClient'; +export * from './TunnelProxy'; // export { IConnectToGitHubWizardContext } from './github/IConnectToGitHubWizardContext'; export * from './pingFunctionApp'; export * from './registerSiteCommand'; @@ -42,11 +43,12 @@ export * from './remoteDebug/startRemoteDebug'; export * from './siteFiles'; export * from './startStreamingLogs'; export * from './swapSlot'; -export * from './tree/DeploymentTreeItem'; export * from './tree/DeploymentsTreeItem'; +export * from './tree/DeploymentTreeItem'; export * from './tree/FileTreeItem'; export * from './tree/FolderTreeItem'; export * from './tree/LogFilesTreeItem'; export * from './tree/SiteFilesTreeItem'; export * from './tryGetSiteResource'; export * from './utils/azureClients'; + From 2d542dee4fbfd2bc0f6816da53e7f4b959630d14 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 12:10:28 -0800 Subject: [PATCH 02/25] Update site name validation --- .../IAppServiceWizardContext.ts | 6 -- .../SiteDomainNameLabelScopeStep.ts | 12 ++-- .../src/createAppService/SiteNameStep.ts | 62 +++++++++++++++---- 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/appservice/src/createAppService/IAppServiceWizardContext.ts b/appservice/src/createAppService/IAppServiceWizardContext.ts index 88715a8ce5..1e055e8187 100644 --- a/appservice/src/createAppService/IAppServiceWizardContext.ts +++ b/appservice/src/createAppService/IAppServiceWizardContext.ts @@ -37,12 +37,6 @@ export interface IAppServiceWizardContext extends IResourceGroupWizardContext, I */ newSiteDomainNameLabelScope?: DomainNameLabelScope; - /** - * Specifies whether or not to display DomainNameLabelScope.ResourceGroup as a pick option. - * This will be defined during `SiteDomainLabelScopeStep.prompt` - */ - omitResourceGroupDomainNameScope?: boolean; - /** * The App Service plan to use. * If an existing plan is picked, this value will be defined after `AppServicePlanListStep.prompt` occurs diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts index 81c473eed8..931bc22cae 100644 --- a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { AzureWizardPromptStep, IAzureQuickPickItem } from '@microsoft/vscode-azext-utils'; +import { AzureWizardPromptStep, IAzureQuickPickItem, openUrl } from '@microsoft/vscode-azext-utils'; import * as vscode from 'vscode'; import { IAppServiceWizardContext } from './IAppServiceWizardContext'; @@ -20,21 +20,19 @@ export class SiteDomainNameLabelScopeStep ex { label: vscode.l10n.t('Tenant'), description: vscode.l10n.t('(recommended)'), data: DomainNameLabelScope.Tenant }, { label: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, { label: vscode.l10n.t('Subscription'), data: DomainNameLabelScope.Subscription }, + { label: vscode.l10n.t('Resource group'), data: DomainNameLabelScope.ResourceGroup }, + { label: vscode.l10n.t('$(link-external) Learn more about domain name label scopes'), data: undefined }, ]; - if (!context.omitResourceGroupDomainNameScope) { - picks.push({ label: vscode.l10n.t('Resource group'), data: DomainNameLabelScope.ResourceGroup }); - } - let result: DomainNameLabelScope | undefined; do { result = (await context.ui.showQuickPick(picks, { - placeHolder: vscode.l10n.t('Select the uniqueness level for your domain name'), + placeHolder: vscode.l10n.t('Select a domain name label scope'), suppressPersistence: true, })).data; if (!result) { - // Todo: Open learn more link + await openUrl('https://aka.ms/AAu2xga'); } } while (!result); diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 36e1dbb796..75e36912ff 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type { ResourceNameAvailability, WebSiteManagementClient } from '@azure/arm-appservice'; +import type { ResourceNameAvailability, Site, WebSiteManagementClient } from '@azure/arm-appservice'; import { createHttpHeaders, createPipelineRequest } from '@azure/core-rest-pipeline'; import { AzExtLocation, AzExtPipelineResponse, AzExtRequestPrepareOptions, LocationListStep, ResourceGroupListStep, StorageAccountListStep, createGenericClient, resourceGroupNamingRules, storageAccountNamingRules } from '@microsoft/vscode-azext-azureutils'; -import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules, nonNullValueAndProp } from '@microsoft/vscode-azext-utils'; +import { AgentInputBoxOptions, AzureNameStep, IAzureAgentInput, IAzureNamingRules, nonNullValue, nonNullValueAndProp } from '@microsoft/vscode-azext-utils'; import * as vscode from 'vscode'; import { createWebSiteClient } from '../utils/azureClients'; import { appInsightsNamingRules } from './AppInsightsListStep'; @@ -79,7 +79,10 @@ export class SiteNameStep extends AzureNameStep { context.newSiteName = (await context.ui.showInputBox(options)).trim(); context.valuesToMask.push(context.newSiteName); + context.relatedNameTask ??= this.generateRelatedName(context, context.newSiteName, this.getRelatedResourceNamingRules(context)); + } + private getRelatedResourceNamingRules(context: SiteNameStepWizardContext): IAzureNamingRules[] { const namingRules: IAzureNamingRules[] = [resourceGroupNamingRules]; if (context.newSiteKind === AppKind.functionapp) { namingRules.push(storageAccountNamingRules); @@ -88,18 +91,18 @@ export class SiteNameStep extends AzureNameStep { } namingRules.push(appInsightsNamingRules); - context.relatedNameTask = this.generateRelatedName(context, context.newSiteName, namingRules); + return namingRules; } - public async getRelatedName(context: IAppServiceWizardContext, name: string): Promise { + public async getRelatedName(context: SiteNameStepWizardContext, name: string): Promise { return await this.generateRelatedName(context, name, appServicePlanNamingRules); } - public shouldPrompt(context: IAppServiceWizardContext): boolean { + public shouldPrompt(context: SiteNameStepWizardContext): boolean { return !context.newSiteName; } - protected async isRelatedNameAvailable(context: IAppServiceWizardContext, name: string): Promise { + protected async isRelatedNameAvailable(context: SiteNameStepWizardContext, name: string): Promise { const tasks: Promise[] = [ResourceGroupListStep.isNameAvailable(context, name)]; if (context.newSiteKind === AppKind.functionapp) { tasks.push(StorageAccountListStep.isNameAvailable(context, name)); @@ -124,13 +127,22 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - private async asyncValidateSiteName(context: IAppServiceWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { - return context.newSiteDomainNameLabelScope && context.newSiteDomainNameLabelScope !== DomainNameLabelScope.Global ? - await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName) : - await this.asyncValidateSiteNameByGlobalScope(sdkClient, name); + // Todo: Leave reference to GitHub comment + private async asyncValidateSiteName(context: SiteNameStepWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { + let validationMessage: string | undefined; + + if (!context.newSiteDomainNameLabelScope || context.newSiteDomainNameLabelScope === DomainNameLabelScope.Global) { + validationMessage ??= await this.asyncValidateGlobalSiteName(sdkClient, name); + } + if (context.newSiteDomainNameLabelScope) { + validationMessage ??= await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); + validationMessage ??= await this.asyncValidateUniqueResourceId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); + } + + return validationMessage; } - private async asyncValidateSiteNameByDomainScope(context: IAppServiceWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { + private async asyncValidateSiteNameByDomainScope(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with non-global domain scope.')); } @@ -142,7 +154,7 @@ export class SiteNameStep extends AzureNameStep { const location: AzExtLocation = await LocationListStep.getLocation(context); const authToken: string = nonNullValueAndProp((await context.credentials.getToken() as { token?: string }), 'token'); - // Todo: Can replace with call to SDK once updated version is out + // Todo: Can potentially replace with call using SDK once the update is available const options: AzExtRequestPrepareOptions = { url: `https://management.azure.com/subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, method: 'POST', @@ -170,7 +182,7 @@ export class SiteNameStep extends AzureNameStep { return !checkNameResponse.nameAvailable ? checkNameResponse.message : undefined; } - private async asyncValidateSiteNameByGlobalScope(client: WebSiteManagementClient, name: string): Promise { + private async asyncValidateGlobalSiteName(client: WebSiteManagementClient, name: string): Promise { const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); if (!nameAvailability.nameAvailable) { return nameAvailability.message; @@ -178,4 +190,28 @@ export class SiteNameStep extends AzureNameStep { return undefined; } } + + private async asyncValidateUniqueResourceId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { + if (!resourceGroupName) { + context.relatedNameTask = this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); + resourceGroupName = await context.relatedNameTask; + } + + try { + const site: Site = await client.webApps.get( + nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify a unique Site ID.')), + siteName + ); + if (site) { + return vscode.l10n.t('A site with name "{0}" already exists.', siteName); + } + } catch (e) { + const statusCode = (e as { statusCode?: number })?.statusCode; + if (statusCode !== 404) { + return vscode.l10n.t('Failed to validate unique site with name "{0}". Please try another name.', siteName); + } + } + + return undefined; + } } From e01dfa5977c6eba8d274022773a062c7f544318b Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 12:38:40 -0800 Subject: [PATCH 03/25] Update domain label scope offering --- .../createAppService/SiteDomainNameLabelScopeStep.ts | 11 +++++------ appservice/src/createAppService/SiteNameStep.ts | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts index 931bc22cae..70c27f3086 100644 --- a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -17,17 +17,16 @@ export enum DomainNameLabelScope { export class SiteDomainNameLabelScopeStep extends AzureWizardPromptStep { public async prompt(context: T): Promise { const picks: IAzureQuickPickItem[] = [ - { label: vscode.l10n.t('Tenant'), description: vscode.l10n.t('(recommended)'), data: DomainNameLabelScope.Tenant }, - { label: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, - { label: vscode.l10n.t('Subscription'), data: DomainNameLabelScope.Subscription }, - { label: vscode.l10n.t('Resource group'), data: DomainNameLabelScope.ResourceGroup }, - { label: vscode.l10n.t('$(link-external) Learn more about domain name label scopes'), data: undefined }, + // Matching the portal which doesn't yet offer ResourceGroup and Subscription level domain scope + { label: vscode.l10n.t('Secure unique default hostname'), description: vscode.l10n.t('Tenant'), data: DomainNameLabelScope.Tenant }, + { label: vscode.l10n.t('Global default hostname'), description: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, + { label: vscode.l10n.t('$(link-external) Learn more about unique default hostname'), data: undefined }, ]; let result: DomainNameLabelScope | undefined; do { result = (await context.ui.showQuickPick(picks, { - placeHolder: vscode.l10n.t('Select a domain name label scope'), + placeHolder: vscode.l10n.t('Select default hostname format'), suppressPersistence: true, })).data; diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 75e36912ff..626dc7a43d 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -154,7 +154,7 @@ export class SiteNameStep extends AzureNameStep { const location: AzExtLocation = await LocationListStep.getLocation(context); const authToken: string = nonNullValueAndProp((await context.credentials.getToken() as { token?: string }), 'token'); - // Todo: Can potentially replace with call using SDK once the update is available + // Todo: Can replace with call using SDK once the update is available const options: AzExtRequestPrepareOptions = { url: `https://management.azure.com/subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, method: 'POST', From f69ea85c8942c997821619cc95d8ab14fecc06b6 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 12:48:38 -0800 Subject: [PATCH 04/25] Update url --- appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts index 70c27f3086..0eb23efe64 100644 --- a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -31,7 +31,7 @@ export class SiteDomainNameLabelScopeStep ex })).data; if (!result) { - await openUrl('https://aka.ms/AAu2xga'); + await openUrl('https://aka.ms/AAu7lhs'); } } while (!result); From cdb75e8e56e141b42cb203a0c327714b29c9a9aa Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:54:24 -0800 Subject: [PATCH 05/25] Improvements to naming/wording --- appservice/src/createAppService/SiteNameStep.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 626dc7a43d..07ac8ae249 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -136,7 +136,7 @@ export class SiteNameStep extends AzureNameStep { } if (context.newSiteDomainNameLabelScope) { validationMessage ??= await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); - validationMessage ??= await this.asyncValidateUniqueResourceId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); + validationMessage ??= await this.asyncValidateUniqueARMId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); } return validationMessage; @@ -144,7 +144,7 @@ export class SiteNameStep extends AzureNameStep { private async asyncValidateSiteNameByDomainScope(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { - throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with non-global domain scope.')); + throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with domain scope.')); } if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { throw new Error(vscode.l10n.t('Internal Error: A resource group name is required when validating a site name with resource group level domain scope.')); @@ -191,7 +191,7 @@ export class SiteNameStep extends AzureNameStep { } } - private async asyncValidateUniqueResourceId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { + private async asyncValidateUniqueARMId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { if (!resourceGroupName) { context.relatedNameTask = this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); resourceGroupName = await context.relatedNameTask; @@ -199,7 +199,7 @@ export class SiteNameStep extends AzureNameStep { try { const site: Site = await client.webApps.get( - nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify a unique Site ID.')), + nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify unique site ID.')), siteName ); if (site) { @@ -208,7 +208,7 @@ export class SiteNameStep extends AzureNameStep { } catch (e) { const statusCode = (e as { statusCode?: number })?.statusCode; if (statusCode !== 404) { - return vscode.l10n.t('Failed to validate unique site with name "{0}". Please try another name.', siteName); + return vscode.l10n.t('Failed to validate name availability for "{0}". Please try another name.', siteName); } } From 3965f7829ccb66e899efa637c98178ed73b34ee8 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 15:47:33 -0800 Subject: [PATCH 06/25] , --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 07ac8ae249..f9035a28b5 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -200,7 +200,7 @@ export class SiteNameStep extends AzureNameStep { try { const site: Site = await client.webApps.get( nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify unique site ID.')), - siteName + siteName, ); if (site) { return vscode.l10n.t('A site with name "{0}" already exists.', siteName); From 2f0ac48b5c16f5bf8b2f383a13c6f26be547d1bb Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 15:52:05 -0800 Subject: [PATCH 07/25] Fix comment --- appservice/src/createAppService/IAppServiceWizardContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/IAppServiceWizardContext.ts b/appservice/src/createAppService/IAppServiceWizardContext.ts index 1e055e8187..4ad4c06751 100644 --- a/appservice/src/createAppService/IAppServiceWizardContext.ts +++ b/appservice/src/createAppService/IAppServiceWizardContext.ts @@ -33,7 +33,7 @@ export interface IAppServiceWizardContext extends IResourceGroupWizardContext, I /** * The domain name label scope for the new site - * This will be defined after `SiteDomainLabelScopeStep.prompt` occurs. + * This will be defined after `SiteDomainNameLabelScopeStep.prompt` occurs. */ newSiteDomainNameLabelScope?: DomainNameLabelScope; From ad82851ac04453df0848f1d0991cb7749a659897 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 3 Feb 2025 16:21:13 -0800 Subject: [PATCH 08/25] Bump utils --- appservice/package-lock.json | 364 +++++++++++++++-------------------- appservice/package.json | 2 +- 2 files changed, 155 insertions(+), 211 deletions(-) diff --git a/appservice/package-lock.json b/appservice/package-lock.json index f5b1075cd3..5df1c5c551 100644 --- a/appservice/package-lock.json +++ b/appservice/package-lock.json @@ -20,7 +20,7 @@ "@azure/storage-blob": "^12.3.0", "@microsoft/vscode-azext-azureutils": "^3.0.0", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.5.0", + "@microsoft/vscode-azext-utils": "^2.5.13", "dayjs": "^1.11.2", "fs-extra": "^10.0.0", "p-retry": "^3.0.1", @@ -585,71 +585,71 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "node_modules/@microsoft/1ds-core-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.0.5.tgz", - "integrity": "sha512-uTOSUoXt/KgnLlGWED+vLLnYCFq1kDFbej+pGAbR+6tMGajCgw3Xz3Xcal0nYhk9RM2hvWWAt5gs6Bu2Si/46g==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.3.5.tgz", + "integrity": "sha512-WozEs1DB8FtqFtPcTilKhMZvhyEEw0bzehl+5S8lvncIIXcAbJx9ga6zpx6XqJ1CxmHAQen4MLgMYCLDBIzcNQ==", "dependencies": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@microsoft/1ds-post-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.0.5.tgz", - "integrity": "sha512-jziJe/nXxgDhnW0sWkXbj9ZfwHXRH6UCn6eGgyWlog3iWP8FgXzna8Rugvct2r43XEqGs6c/NKxuFXAVtyGXjg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.3.5.tgz", + "integrity": "sha512-AavxRU6qrzZuqDn2W5tiQ0bIqAWQrkyLV7VUn4ZzeB/0ekKCgfBouT69GpmfL1fu2wztlFcQaMpj/V8PXIxW+A==", "dependencies": { - "@microsoft/1ds-core-js": "4.0.5", + "@microsoft/1ds-core-js": "4.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@microsoft/applicationinsights-channel-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.7.tgz", - "integrity": "sha512-3y8ct8V2bGo7QaYVrfQcWZeOci2tUZhXkme3k7nKa2P7upSX/1d+dPF12EelxrtWVLxtfCQJkk+2W4M1AyejGQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.3.5.tgz", + "integrity": "sha512-q9iE5alabgddwnxIDxgYLwC/3OMjYNOPk87p3jY+KxO0UmJGhiv7C1uI62zpx4AHBGT2+q6pMbIZdgld9TmMrw==", "dependencies": { - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-common": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.7.tgz", - "integrity": "sha512-boumvLA7LZu0NmwT9ThpTAI64BNYUlOkFNcjUbYeKNEaE6CBPGX/z25XXlYu+j4hHldDaCn9zC1LuN7AuoMJSA==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.3.5.tgz", + "integrity": "sha512-zZgMOY3ePBhjTrZ8+MXwAb0Y+Yi4iVDKOqIaz/KoCmj1BxX5JKFgaqYiN8Tvu5O0YPJpEKS4coYXRHbStDm/Hw==", "dependencies": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-core-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.7.tgz", - "integrity": "sha512-sVnnVW4fWXzZdtUTVjuwH3xGa1cj+tW7r72voMZzyuNOZ41fBOCK9AqoV0nKP5VCgNjySwn6Rpbw82I4TKKosQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.3.5.tgz", + "integrity": "sha512-8Gg18W5eOE3usXtkZ5iOqWAMU97hyjb7Oi1CtkWmxEoMUHMlQmqUD62n9BmVq/s5YfbUihGZHxc0keMJy0txAA==", "dependencies": { "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/applicationinsights-shims": { @@ -661,20 +661,20 @@ } }, "node_modules/@microsoft/applicationinsights-web-basic": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.7.tgz", - "integrity": "sha512-D1Zuv/UMwm37bosZi7aZgjLt4xXTAe98ttAoSel/JThglZ2grYBixBHUjgAGzyno8u9JZElPviRHIAWWYAk3TQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.3.5.tgz", + "integrity": "sha512-nYLyxjO3p74SHxq/JctDndD6P/3YBLY1F/F+h2AdJsaMavSGudU7ylMb2IMQc1X+yqFZ4H4cUvkxljj/SiBi2g==", "dependencies": { - "@microsoft/applicationinsights-channel-js": "3.0.7", - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-channel-js": "3.3.5", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" }, "peerDependencies": { - "tslib": "*" + "tslib": ">= 1.0.0" } }, "node_modules/@microsoft/dynamicproto-js": { @@ -1062,18 +1062,18 @@ } }, "node_modules/@microsoft/vscode-azext-utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", - "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.13.tgz", + "integrity": "sha512-0x9uW0VPCon/K3XwmedMuRc6F6S0b92FAlvaJHtzEi4EW1mek/1/nK8gLR2AP7rEaLOtq7sewoKdr9ejfs165g==", "dependencies": { - "@microsoft/vscode-azureresources-api": "^2.0.4", - "@vscode/extension-telemetry": "^0.9.0", + "@microsoft/vscode-azureresources-api": "^2.3.1", + "@vscode/extension-telemetry": "^0.9.6", "dayjs": "^1.11.2", "escape-string-regexp": "^2.0.0", "html-to-text": "^8.2.0", "semver": "^7.3.7", "uuid": "^9.0.0", - "vscode-tas-client": "^0.1.47", + "vscode-tas-client": "^0.1.84", "vscode-uri": "^3.0.6" }, "peerDependencies": { @@ -1089,22 +1089,25 @@ } }, "node_modules/@microsoft/vscode-azureresources-api": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.0.4.tgz", - "integrity": "sha512-LridV1h2rCydrBzEpwy+pUIUx61GpZNwrK04G7LdlhoxHrzuM/WAoy8jXaSC/FSKSsXD1QXuE6u/YofEfsuKeg==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.3.2.tgz", + "integrity": "sha512-hwG8Q1ywk7faPIyKLRT5Lfk9usl5i0mIxqyVEWxs4gBi5Jfq4d90WEJbHJLX72v6HS+4KQCKJ0h0XhNS7y4OZg==", + "peerDependencies": { + "@azure/ms-rest-azure-env": "^2.0.0" + } }, "node_modules/@nevware21/ts-async": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.4.0.tgz", - "integrity": "sha512-dbV826TTehQIBIJjh8GDSbwn1Z6+cnkyNbRlpcpdBPH8mROD2zabIUKqWcw9WRdTjjUIm21K+OR4DXWlAyOVTQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.4.tgz", + "integrity": "sha512-IBTyj29GwGlxfzXw2NPnzty+w0Adx61Eze1/lknH/XIVdxtF9UnOpk76tnrHXWa6j84a1RR9hsOcHQPFv9qJjA==", "dependencies": { - "@nevware21/ts-utils": ">= 0.10.0 < 2.x" + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "node_modules/@nevware21/ts-utils": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.10.4.tgz", - "integrity": "sha512-+QSEh9TZ7SFwZEEyIvP8NabL5I5WFE/gvk4LXtW4LjWyTEc/6t2Hog6r1MmY3hIQG9tLe6fARIAXjAQ/M8Kb6A==" + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.6.tgz", + "integrity": "sha512-OUUJTh3fnaUSzg9DEHgv3d7jC+DnPL65mIO7RaR+jWve7+MmcgIvF79gY97DPQ4frH+IpNR78YAYd/dW4gK3kg==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1738,13 +1741,13 @@ "dev": true }, "node_modules/@vscode/extension-telemetry": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.2.tgz", - "integrity": "sha512-O6VMCDkzypjULhgy2l6fih3c3fExPmSj7aewtW5jBJYgXcIIjtkJOttIfnKOCP4S8sNfc6xc1Do4MbUDmhduEw==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.8.tgz", + "integrity": "sha512-7YcKoUvmHlIB8QYCE4FNzt3ErHi9gQPhdCM3ZWtpw1bxPT0I+lMdx52KHlzTNoJzQ2NvMX7HyzyDwBEiMgTrWQ==", "dependencies": { - "@microsoft/1ds-core-js": "^4.0.3", - "@microsoft/1ds-post-js": "^4.0.3", - "@microsoft/applicationinsights-web-basic": "^3.0.6" + "@microsoft/1ds-core-js": "^4.3.4", + "@microsoft/1ds-post-js": "^4.3.4", + "@microsoft/applicationinsights-web-basic": "^3.3.4" }, "engines": { "vscode": "^1.75.0" @@ -2150,16 +2153,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3537,25 +3530,6 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5570,11 +5544,6 @@ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -6206,12 +6175,9 @@ } }, "node_modules/tas-client": { - "version": "0.1.73", - "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz", - "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==", - "dependencies": { - "axios": "^1.6.1" - } + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz", + "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg==" }, "node_modules/terser": { "version": "5.16.6", @@ -6556,14 +6522,14 @@ } }, "node_modules/vscode-tas-client": { - "version": "0.1.75", - "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz", - "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==", + "version": "0.1.84", + "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz", + "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==", "dependencies": { - "tas-client": "0.1.73" + "tas-client": "0.2.33" }, "engines": { - "vscode": "^1.19.1" + "vscode": "^1.85.0" } }, "node_modules/vscode-uri": { @@ -7335,62 +7301,62 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "@microsoft/1ds-core-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.0.5.tgz", - "integrity": "sha512-uTOSUoXt/KgnLlGWED+vLLnYCFq1kDFbej+pGAbR+6tMGajCgw3Xz3Xcal0nYhk9RM2hvWWAt5gs6Bu2Si/46g==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-core-js/-/1ds-core-js-4.3.5.tgz", + "integrity": "sha512-WozEs1DB8FtqFtPcTilKhMZvhyEEw0bzehl+5S8lvncIIXcAbJx9ga6zpx6XqJ1CxmHAQen4MLgMYCLDBIzcNQ==", "requires": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/1ds-post-js": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.0.5.tgz", - "integrity": "sha512-jziJe/nXxgDhnW0sWkXbj9ZfwHXRH6UCn6eGgyWlog3iWP8FgXzna8Rugvct2r43XEqGs6c/NKxuFXAVtyGXjg==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/1ds-post-js/-/1ds-post-js-4.3.5.tgz", + "integrity": "sha512-AavxRU6qrzZuqDn2W5tiQ0bIqAWQrkyLV7VUn4ZzeB/0ekKCgfBouT69GpmfL1fu2wztlFcQaMpj/V8PXIxW+A==", "requires": { - "@microsoft/1ds-core-js": "4.0.5", + "@microsoft/1ds-core-js": "4.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-channel-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.7.tgz", - "integrity": "sha512-3y8ct8V2bGo7QaYVrfQcWZeOci2tUZhXkme3k7nKa2P7upSX/1d+dPF12EelxrtWVLxtfCQJkk+2W4M1AyejGQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.3.5.tgz", + "integrity": "sha512-q9iE5alabgddwnxIDxgYLwC/3OMjYNOPk87p3jY+KxO0UmJGhiv7C1uI62zpx4AHBGT2+q6pMbIZdgld9TmMrw==", "requires": { - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-common": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.7.tgz", - "integrity": "sha512-boumvLA7LZu0NmwT9ThpTAI64BNYUlOkFNcjUbYeKNEaE6CBPGX/z25XXlYu+j4hHldDaCn9zC1LuN7AuoMJSA==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.3.5.tgz", + "integrity": "sha512-zZgMOY3ePBhjTrZ8+MXwAb0Y+Yi4iVDKOqIaz/KoCmj1BxX5JKFgaqYiN8Tvu5O0YPJpEKS4coYXRHbStDm/Hw==", "requires": { - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-core-js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.7.tgz", - "integrity": "sha512-sVnnVW4fWXzZdtUTVjuwH3xGa1cj+tW7r72voMZzyuNOZ41fBOCK9AqoV0nKP5VCgNjySwn6Rpbw82I4TKKosQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.3.5.tgz", + "integrity": "sha512-8Gg18W5eOE3usXtkZ5iOqWAMU97hyjb7Oi1CtkWmxEoMUHMlQmqUD62n9BmVq/s5YfbUihGZHxc0keMJy0txAA==", "requires": { "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/applicationinsights-shims": { @@ -7402,17 +7368,17 @@ } }, "@microsoft/applicationinsights-web-basic": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.7.tgz", - "integrity": "sha512-D1Zuv/UMwm37bosZi7aZgjLt4xXTAe98ttAoSel/JThglZ2grYBixBHUjgAGzyno8u9JZElPviRHIAWWYAk3TQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.3.5.tgz", + "integrity": "sha512-nYLyxjO3p74SHxq/JctDndD6P/3YBLY1F/F+h2AdJsaMavSGudU7ylMb2IMQc1X+yqFZ4H4cUvkxljj/SiBi2g==", "requires": { - "@microsoft/applicationinsights-channel-js": "3.0.7", - "@microsoft/applicationinsights-common": "3.0.7", - "@microsoft/applicationinsights-core-js": "3.0.7", + "@microsoft/applicationinsights-channel-js": "3.3.5", + "@microsoft/applicationinsights-common": "3.3.5", + "@microsoft/applicationinsights-core-js": "3.3.5", "@microsoft/applicationinsights-shims": "3.0.1", - "@microsoft/dynamicproto-js": "^2.0.2", - "@nevware21/ts-async": ">= 0.3.0 < 2.x", - "@nevware21/ts-utils": ">= 0.10.1 < 2.x" + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@microsoft/dynamicproto-js": { @@ -7712,18 +7678,18 @@ } }, "@microsoft/vscode-azext-utils": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.1.tgz", - "integrity": "sha512-K9S25xSZ5jEy5ofsLGdgzdXkyqzYhdJuBNkSRMa/7Qt6S+YtspQ4qwX6gNGvlMHE3gPAXDHqxvn+yPmm4s5uYg==", + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.5.13.tgz", + "integrity": "sha512-0x9uW0VPCon/K3XwmedMuRc6F6S0b92FAlvaJHtzEi4EW1mek/1/nK8gLR2AP7rEaLOtq7sewoKdr9ejfs165g==", "requires": { - "@microsoft/vscode-azureresources-api": "^2.0.4", - "@vscode/extension-telemetry": "^0.9.0", + "@microsoft/vscode-azureresources-api": "^2.3.1", + "@vscode/extension-telemetry": "^0.9.6", "dayjs": "^1.11.2", "escape-string-regexp": "^2.0.0", "html-to-text": "^8.2.0", "semver": "^7.3.7", "uuid": "^9.0.0", - "vscode-tas-client": "^0.1.47", + "vscode-tas-client": "^0.1.84", "vscode-uri": "^3.0.6" }, "dependencies": { @@ -7735,22 +7701,23 @@ } }, "@microsoft/vscode-azureresources-api": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.0.4.tgz", - "integrity": "sha512-LridV1h2rCydrBzEpwy+pUIUx61GpZNwrK04G7LdlhoxHrzuM/WAoy8jXaSC/FSKSsXD1QXuE6u/YofEfsuKeg==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@microsoft/vscode-azureresources-api/-/vscode-azureresources-api-2.3.2.tgz", + "integrity": "sha512-hwG8Q1ywk7faPIyKLRT5Lfk9usl5i0mIxqyVEWxs4gBi5Jfq4d90WEJbHJLX72v6HS+4KQCKJ0h0XhNS7y4OZg==", + "requires": {} }, "@nevware21/ts-async": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.4.0.tgz", - "integrity": "sha512-dbV826TTehQIBIJjh8GDSbwn1Z6+cnkyNbRlpcpdBPH8mROD2zabIUKqWcw9WRdTjjUIm21K+OR4DXWlAyOVTQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.4.tgz", + "integrity": "sha512-IBTyj29GwGlxfzXw2NPnzty+w0Adx61Eze1/lknH/XIVdxtF9UnOpk76tnrHXWa6j84a1RR9hsOcHQPFv9qJjA==", "requires": { - "@nevware21/ts-utils": ">= 0.10.0 < 2.x" + "@nevware21/ts-utils": ">= 0.11.6 < 2.x" } }, "@nevware21/ts-utils": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.10.4.tgz", - "integrity": "sha512-+QSEh9TZ7SFwZEEyIvP8NabL5I5WFE/gvk4LXtW4LjWyTEc/6t2Hog6r1MmY3hIQG9tLe6fARIAXjAQ/M8Kb6A==" + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.11.6.tgz", + "integrity": "sha512-OUUJTh3fnaUSzg9DEHgv3d7jC+DnPL65mIO7RaR+jWve7+MmcgIvF79gY97DPQ4frH+IpNR78YAYd/dW4gK3kg==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -8236,13 +8203,13 @@ "dev": true }, "@vscode/extension-telemetry": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.2.tgz", - "integrity": "sha512-O6VMCDkzypjULhgy2l6fih3c3fExPmSj7aewtW5jBJYgXcIIjtkJOttIfnKOCP4S8sNfc6xc1Do4MbUDmhduEw==", + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.9.8.tgz", + "integrity": "sha512-7YcKoUvmHlIB8QYCE4FNzt3ErHi9gQPhdCM3ZWtpw1bxPT0I+lMdx52KHlzTNoJzQ2NvMX7HyzyDwBEiMgTrWQ==", "requires": { - "@microsoft/1ds-core-js": "^4.0.3", - "@microsoft/1ds-post-js": "^4.0.3", - "@microsoft/applicationinsights-web-basic": "^3.0.6" + "@microsoft/1ds-core-js": "^4.3.4", + "@microsoft/1ds-post-js": "^4.3.4", + "@microsoft/applicationinsights-web-basic": "^3.3.4" } }, "@vscode/test-electron": { @@ -8578,16 +8545,6 @@ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, - "axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", - "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -9626,11 +9583,6 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, - "follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" - }, "for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -11097,11 +11049,6 @@ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -11536,12 +11483,9 @@ } }, "tas-client": { - "version": "0.1.73", - "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz", - "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==", - "requires": { - "axios": "^1.6.1" - } + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz", + "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg==" }, "terser": { "version": "5.16.6", @@ -11795,11 +11739,11 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "vscode-tas-client": { - "version": "0.1.75", - "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz", - "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==", + "version": "0.1.84", + "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz", + "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==", "requires": { - "tas-client": "0.1.73" + "tas-client": "0.2.33" } }, "vscode-uri": { diff --git a/appservice/package.json b/appservice/package.json index dcc2ad450a..71e5a08de4 100644 --- a/appservice/package.json +++ b/appservice/package.json @@ -42,7 +42,7 @@ "@azure/storage-blob": "^12.3.0", "@microsoft/vscode-azext-azureutils": "^3.0.0", "@microsoft/vscode-azext-github": "^1.0.0", - "@microsoft/vscode-azext-utils": "^2.5.0", + "@microsoft/vscode-azext-utils": "^2.5.13", "dayjs": "^1.11.2", "fs-extra": "^10.0.0", "p-retry": "^3.0.1", From 961f1b667526a181b02880d4dd41a45a7ccbc808 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:25:22 -0800 Subject: [PATCH 09/25] Add additional validation rule --- appservice/src/createAppService/SiteNameStep.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index f9035a28b5..5dcc1f9add 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -129,11 +129,13 @@ export class SiteNameStep extends AzureNameStep { // Todo: Leave reference to GitHub comment private async asyncValidateSiteName(context: SiteNameStepWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { - let validationMessage: string | undefined; + name = name.trim(); + let validationMessage: string | undefined; if (!context.newSiteDomainNameLabelScope || context.newSiteDomainNameLabelScope === DomainNameLabelScope.Global) { validationMessage ??= await this.asyncValidateGlobalSiteName(sdkClient, name); } + if (context.newSiteDomainNameLabelScope) { validationMessage ??= await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); validationMessage ??= await this.asyncValidateUniqueARMId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); @@ -179,7 +181,18 @@ export class SiteNameStep extends AzureNameStep { nameAvailable?: boolean; reason?: string; }; - return !checkNameResponse.nameAvailable ? checkNameResponse.message : undefined; + + if (!checkNameResponse.nameAvailable) { + // If site name input is >=47 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA + if (domainNameScope === DomainNameLabelScope.Global && checkNameResponse.message && checkNameResponse.message.length >= 47) { + if (/must be less than \d{2} chars/i.test(checkNameResponse.message)) { + return undefined; + } + } + return checkNameResponse.message; + } + + return undefined; } private async asyncValidateGlobalSiteName(client: WebSiteManagementClient, name: string): Promise { From 393a960db0f9206f4e4f0c84acab8098561d6015 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 13:28:12 -0800 Subject: [PATCH 10/25] Rename methods --- appservice/src/createAppService/SiteNameStep.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 5dcc1f9add..2aef44aea3 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -133,18 +133,18 @@ export class SiteNameStep extends AzureNameStep { let validationMessage: string | undefined; if (!context.newSiteDomainNameLabelScope || context.newSiteDomainNameLabelScope === DomainNameLabelScope.Global) { - validationMessage ??= await this.asyncValidateGlobalSiteName(sdkClient, name); + validationMessage ??= await this.asyncValidateGlobalCNA(sdkClient, name); } if (context.newSiteDomainNameLabelScope) { - validationMessage ??= await this.asyncValidateSiteNameByDomainScope(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); + validationMessage ??= await this.asyncValidateRegionalCNA(context, context.newSiteDomainNameLabelScope, name, context.resourceGroup?.name ?? context.newResourceGroupName); validationMessage ??= await this.asyncValidateUniqueARMId(context, sdkClient, name, context.resourceGroup?.name ?? context.newResourceGroupName); } return validationMessage; } - private async asyncValidateSiteNameByDomainScope(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { + private async asyncValidateRegionalCNA(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with domain scope.')); } @@ -185,6 +185,7 @@ export class SiteNameStep extends AzureNameStep { if (!checkNameResponse.nameAvailable) { // If site name input is >=47 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA if (domainNameScope === DomainNameLabelScope.Global && checkNameResponse.message && checkNameResponse.message.length >= 47) { + // Ensure the error message is the expected character validation error message before ignoring it if (/must be less than \d{2} chars/i.test(checkNameResponse.message)) { return undefined; } @@ -195,7 +196,7 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - private async asyncValidateGlobalSiteName(client: WebSiteManagementClient, name: string): Promise { + private async asyncValidateGlobalCNA(client: WebSiteManagementClient, name: string): Promise { const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); if (!nameAvailability.nameAvailable) { return nameAvailability.message; From 8ee65947972c11ac7d46dd31d899610e0cb0c3f8 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:20:14 -0800 Subject: [PATCH 11/25] Reorder methods --- .../src/createAppService/SiteNameStep.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 2aef44aea3..b33eb417c2 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -144,6 +144,15 @@ export class SiteNameStep extends AzureNameStep { return validationMessage; } + private async asyncValidateGlobalCNA(client: WebSiteManagementClient, name: string): Promise { + const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); + if (!nameAvailability.nameAvailable) { + return nameAvailability.message; + } else { + return undefined; + } + } + private async asyncValidateRegionalCNA(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with domain scope.')); @@ -174,7 +183,6 @@ export class SiteNameStep extends AzureNameStep { const client = await createGenericClient(context, undefined); const pipelineResponse = await client.sendRequest(createPipelineRequest(options)) as AzExtPipelineResponse; - const checkNameResponse = pipelineResponse.parsedBody as { hostName?: string; message?: string; @@ -196,15 +204,6 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - private async asyncValidateGlobalCNA(client: WebSiteManagementClient, name: string): Promise { - const nameAvailability: ResourceNameAvailability = await client.checkNameAvailability(name, 'Site'); - if (!nameAvailability.nameAvailable) { - return nameAvailability.message; - } else { - return undefined; - } - } - private async asyncValidateUniqueARMId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { if (!resourceGroupName) { context.relatedNameTask = this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); From fdfdaa347b38779fbbd2a566df65a1421889a051 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:57:00 -0800 Subject: [PATCH 12/25] Add reference to github comment --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index b33eb417c2..dd7e351a55 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -127,7 +127,7 @@ export class SiteNameStep extends AzureNameStep { return undefined; } - // Todo: Leave reference to GitHub comment + // For comprehensive breakdown of validation logic, please refer to: https://github.com/microsoft/vscode-azuretools/pull/1882#issue-2828801875 private async asyncValidateSiteName(context: SiteNameStepWizardContext, sdkClient: WebSiteManagementClient, name: string): Promise { name = name.trim(); From 32905dd3b699b66396a235a053a257b21e256e64 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 14:58:12 -0800 Subject: [PATCH 13/25] Improve internal error message --- appservice/src/createAppService/SiteNameStep.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index dd7e351a55..e9515e5eb0 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -155,10 +155,10 @@ export class SiteNameStep extends AzureNameStep { private async asyncValidateRegionalCNA(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { - throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with domain scope.')); + throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with regional CNA.')); } if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { - throw new Error(vscode.l10n.t('Internal Error: A resource group name is required when validating a site name with resource group level domain scope.')); + throw new Error(vscode.l10n.t('Internal Error: A resource group name is required when validating a site name via regional CNA.')); } const apiVersion: string = '2024-04-01'; From 255dd3d0a1fb230275ef3ff1836ae70ff8f1e819 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:01:06 -0800 Subject: [PATCH 14/25] Fix site name check --- appservice/src/createAppService/SiteNameStep.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index e9515e5eb0..d11cb912c0 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -192,7 +192,11 @@ export class SiteNameStep extends AzureNameStep { if (!checkNameResponse.nameAvailable) { // If site name input is >=47 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA - if (domainNameScope === DomainNameLabelScope.Global && checkNameResponse.message && checkNameResponse.message.length >= 47) { + if ( + domainNameScope === DomainNameLabelScope.Global && + checkNameResponse.message && + siteName.length >= 47 + ) { // Ensure the error message is the expected character validation error message before ignoring it if (/must be less than \d{2} chars/i.test(checkNameResponse.message)) { return undefined; From f531bca9de491b410cad5af1a6858d9f033ff182 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:03:19 -0800 Subject: [PATCH 15/25] Tweak internal error message some more --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index d11cb912c0..4f89ef042d 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -158,7 +158,7 @@ export class SiteNameStep extends AzureNameStep { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with regional CNA.')); } if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { - throw new Error(vscode.l10n.t('Internal Error: A resource group name is required when validating a site name via regional CNA.')); + throw new Error(vscode.l10n.t('Internal Error: A resource group name is required for validating a resource group scoped site with regional CNA.')); } const apiVersion: string = '2024-04-01'; From 3bed081768312aa679a90b702484ff76dd96f633 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:05:15 -0800 Subject: [PATCH 16/25] Tweak error message some more --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index 4f89ef042d..ac36f32c52 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -158,7 +158,7 @@ export class SiteNameStep extends AzureNameStep { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with regional CNA.')); } if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { - throw new Error(vscode.l10n.t('Internal Error: A resource group name is required for validating a resource group scoped site with regional CNA.')); + throw new Error(vscode.l10n.t('Internal Error: A resource group name is required for validating this level of domain name scope.')); } const apiVersion: string = '2024-04-01'; From 6db55db1dc7021689685f825b50171f2cd6f153c Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:35:57 -0800 Subject: [PATCH 17/25] Tweaking if statements --- appservice/src/createAppService/SiteNameStep.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index ac36f32c52..db1ef2bcdb 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -192,13 +192,9 @@ export class SiteNameStep extends AzureNameStep { if (!checkNameResponse.nameAvailable) { // If site name input is >=47 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA - if ( - domainNameScope === DomainNameLabelScope.Global && - checkNameResponse.message && - siteName.length >= 47 - ) { + if (domainNameScope === DomainNameLabelScope.Global && siteName.length >= 47) { // Ensure the error message is the expected character validation error message before ignoring it - if (/must be less than \d{2} chars/i.test(checkNameResponse.message)) { + if (checkNameResponse.message && /must be less than \d{2} chars/i.test(checkNameResponse.message)) { return undefined; } } From 7664052f039eba5dea1ffad5aec6ba4197a0a45a Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:16:33 -0800 Subject: [PATCH 18/25] Feedback --- appservice/src/createAppService/SiteNameStep.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index db1ef2bcdb..e9a5b7064c 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -156,8 +156,7 @@ export class SiteNameStep extends AzureNameStep { private async asyncValidateRegionalCNA(context: SiteNameStepWizardContext, domainNameScope: DomainNameLabelScope, siteName: string, resourceGroupName?: string): Promise { if (!LocationListStep.hasLocation(context)) { throw new Error(vscode.l10n.t('Internal Error: A location is required when validating a site name with regional CNA.')); - } - if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { + } else if (domainNameScope === DomainNameLabelScope.ResourceGroup && !resourceGroupName) { throw new Error(vscode.l10n.t('Internal Error: A resource group name is required for validating this level of domain name scope.')); } @@ -167,7 +166,7 @@ export class SiteNameStep extends AzureNameStep { // Todo: Can replace with call using SDK once the update is available const options: AzExtRequestPrepareOptions = { - url: `https://management.azure.com/subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, + url: `${context.environment.resourceManagerEndpointUrl}subscriptions/${context.subscriptionId}/providers/Microsoft.Web/locations/${location.name}/checknameavailability?api-version=${apiVersion}`, method: 'POST', headers: createHttpHeaders({ 'Content-Type': 'application/json', From fc1c6a61184966293113e2f197693b761e666449 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:46:42 -0800 Subject: [PATCH 19/25] Add additional validation for regional CNA character limit --- .../src/createAppService/SiteNameStep.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index e9a5b7064c..cd2a11d977 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -26,6 +26,8 @@ const siteNamingRules: IAzureNamingRules = { invalidCharsRegExp: /[^a-zA-Z0-9\-]/ }; +const regionalCNAMaxLength: number = 46; + export class SiteNameStep extends AzureNameStep { private _siteFor: "functionApp" | "containerizedFunctionApp" | undefined; @@ -72,7 +74,7 @@ export class SiteNameStep extends AzureNameStep { const options: AgentInputBoxOptions = { prompt, placeHolder, - validateInput: (name: string): string | undefined => this.validateSiteName(name), + validateInput: (name: string): string | undefined => this.validateSiteName(context, name), asyncValidationTask: async (name: string): Promise => await this.asyncValidateSiteName(context, client, name), agentMetadata: agentMetadata }; @@ -113,11 +115,16 @@ export class SiteNameStep extends AzureNameStep { return (await Promise.all(tasks)).every((v: boolean) => v); } - private validateSiteName(name: string): string | undefined { + private validateSiteName(context: SiteNameStepWizardContext, name: string): string | undefined { name = name.trim(); - if (name.length < siteNamingRules.minLength || name.length > siteNamingRules.maxLength) { - return vscode.l10n.t('The name must be between {0} and {1} characters.', siteNamingRules.minLength, siteNamingRules.maxLength); + let maxLength: number = siteNamingRules.maxLength; + if (context.newSiteDomainNameLabelScope && context.newSiteDomainNameLabelScope !== DomainNameLabelScope.Global) { + maxLength = regionalCNAMaxLength; + } + + if (name.length < siteNamingRules.minLength || name.length > maxLength) { + return vscode.l10n.t('The name must be between {0} and {1} characters.', siteNamingRules.minLength, maxLength); } else if (this._siteFor === "containerizedFunctionApp" && (!/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(name))) { return vscode.l10n.t("A name must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character and cannot have '--'."); } else if (siteNamingRules.invalidCharsRegExp.test(name)) { @@ -190,8 +197,8 @@ export class SiteNameStep extends AzureNameStep { }; if (!checkNameResponse.nameAvailable) { - // If site name input is >=47 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA - if (domainNameScope === DomainNameLabelScope.Global && siteName.length >= 47) { + // If site name input is greater than 46 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA + if (domainNameScope === DomainNameLabelScope.Global && siteName.length > regionalCNAMaxLength) { // Ensure the error message is the expected character validation error message before ignoring it if (checkNameResponse.message && /must be less than \d{2} chars/i.test(checkNameResponse.message)) { return undefined; From c25f5657a0941e76f234793361a0e998abd7bea1 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 5 Feb 2025 12:51:04 -0800 Subject: [PATCH 20/25] Bump version --- appservice/package-lock.json | 4 ++-- appservice/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appservice/package-lock.json b/appservice/package-lock.json index 5df1c5c551..52ea96dad7 100644 --- a/appservice/package-lock.json +++ b/appservice/package-lock.json @@ -1,12 +1,12 @@ { "name": "@microsoft/vscode-azext-azureappservice", - "version": "3.3.1", + "version": "3.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@microsoft/vscode-azext-azureappservice", - "version": "3.3.1", + "version": "3.4.0", "license": "MIT", "dependencies": { "@azure/abort-controller": "^1.0.4", diff --git a/appservice/package.json b/appservice/package.json index 71e5a08de4..c568cdbacf 100644 --- a/appservice/package.json +++ b/appservice/package.json @@ -1,7 +1,7 @@ { "name": "@microsoft/vscode-azext-azureappservice", "author": "Microsoft Corporation", - "version": "3.3.1", + "version": "3.4.0", "description": "Common tools for developing Azure App Service extensions for VS Code", "tags": [ "azure", From da1ed4115e78b4d0c1b30dde0bfdac64802d3c6f Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:01:43 -0800 Subject: [PATCH 21/25] Update learn more link --- .../src/createAppService/SiteDomainNameLabelScopeStep.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts index 0eb23efe64..a65aed7ff8 100644 --- a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -22,16 +22,18 @@ export class SiteDomainNameLabelScopeStep ex { label: vscode.l10n.t('Global default hostname'), description: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, { label: vscode.l10n.t('$(link-external) Learn more about unique default hostname'), data: undefined }, ]; + const learnMoreUrl: string = 'https://aka.ms/AAu7lhs'; let result: DomainNameLabelScope | undefined; do { result = (await context.ui.showQuickPick(picks, { placeHolder: vscode.l10n.t('Select default hostname format'), suppressPersistence: true, + learnMoreLink: learnMoreUrl, })).data; if (!result) { - await openUrl('https://aka.ms/AAu7lhs'); + await openUrl(learnMoreUrl); } } while (!result); From c6c8cc798b8bdfd38ca59a98afba814bb6cde2e3 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Mon, 10 Feb 2025 15:13:30 -0800 Subject: [PATCH 22/25] Update regionalCNAMaxLength --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index cd2a11d977..f972e015d4 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -26,7 +26,7 @@ const siteNamingRules: IAzureNamingRules = { invalidCharsRegExp: /[^a-zA-Z0-9\-]/ }; -const regionalCNAMaxLength: number = 46; +const regionalCNAMaxLength: number = 43; export class SiteNameStep extends AzureNameStep { private _siteFor: "functionApp" | "containerizedFunctionApp" | undefined; From fa06cfe8ce77ced59a357a4b21e489dd1a6451bf Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Wed, 26 Feb 2025 13:37:44 -0800 Subject: [PATCH 23/25] PM Feedback --- .../src/createAppService/SiteDomainNameLabelScopeStep.ts | 2 +- appservice/src/createAppService/SiteNameStep.ts | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts index a65aed7ff8..2bb206b11a 100644 --- a/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts +++ b/appservice/src/createAppService/SiteDomainNameLabelScopeStep.ts @@ -18,7 +18,7 @@ export class SiteDomainNameLabelScopeStep ex public async prompt(context: T): Promise { const picks: IAzureQuickPickItem[] = [ // Matching the portal which doesn't yet offer ResourceGroup and Subscription level domain scope - { label: vscode.l10n.t('Secure unique default hostname'), description: vscode.l10n.t('Tenant'), data: DomainNameLabelScope.Tenant }, + { label: vscode.l10n.t('Secure unique default hostname'), description: vscode.l10n.t('Tenant Scope'), data: DomainNameLabelScope.Tenant }, { label: vscode.l10n.t('Global default hostname'), description: vscode.l10n.t('Global'), data: DomainNameLabelScope.Global }, { label: vscode.l10n.t('$(link-external) Learn more about unique default hostname'), data: undefined }, ]; diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index f972e015d4..efda65d39b 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -217,12 +217,10 @@ export class SiteNameStep extends AzureNameStep { } try { - const site: Site = await client.webApps.get( - nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify unique site ID.')), - siteName, - ); + const rgName: string = nonNullValue(resourceGroupName, vscode.l10n.t('Internal Error: A resource group name must be provided to verify unique site ID.')); + const site: Site = await client.webApps.get(rgName, siteName); if (site) { - return vscode.l10n.t('A site with name "{0}" already exists.', siteName); + return vscode.l10n.t('A site with name "{0}" already exists in resource group "{1}".', siteName, rgName); } } catch (e) { const statusCode = (e as { statusCode?: number })?.statusCode; From a3888a4ccd08692be2e32e00baa54056faadc13a Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:10:31 -0800 Subject: [PATCH 24/25] More feedback --- appservice/src/createAppService/SiteNameStep.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index efda65d39b..aac0793673 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -26,6 +26,9 @@ const siteNamingRules: IAzureNamingRules = { invalidCharsRegExp: /[^a-zA-Z0-9\-]/ }; +// Selecting the Tenant domain label scope actually fails if over 43 chars long, even though the CNA validation would otherwise say it's fine. +// Setting the limit to 43 chars seems to completely fix the issue and is the same number the portal is using. +// See: https://github.com/microsoft/vscode-azuretools/pull/1882#issue-2828801875 const regionalCNAMaxLength: number = 43; export class SiteNameStep extends AzureNameStep { @@ -197,7 +200,7 @@ export class SiteNameStep extends AzureNameStep { }; if (!checkNameResponse.nameAvailable) { - // If site name input is greater than 46 chars, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA + // For global domain scope, if site name input is greater than regionalCNAMaxLength, ignore result of regional CNA because it inherently has a shorter character limit than Global CNA if (domainNameScope === DomainNameLabelScope.Global && siteName.length > regionalCNAMaxLength) { // Ensure the error message is the expected character validation error message before ignoring it if (checkNameResponse.message && /must be less than \d{2} chars/i.test(checkNameResponse.message)) { @@ -212,7 +215,7 @@ export class SiteNameStep extends AzureNameStep { private async asyncValidateUniqueARMId(context: SiteNameStepWizardContext, client: WebSiteManagementClient, siteName: string, resourceGroupName?: string): Promise { if (!resourceGroupName) { - context.relatedNameTask = this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); + context.relatedNameTask ??= this.generateRelatedName(context, siteName, this.getRelatedResourceNamingRules(context)); resourceGroupName = await context.relatedNameTask; } From 6200391f20220bac1a51e7ef131baaa7918cab87 Mon Sep 17 00:00:00 2001 From: MicroFish91 <40250218+MicroFish91@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:12:27 -0800 Subject: [PATCH 25/25] Improve comment --- appservice/src/createAppService/SiteNameStep.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appservice/src/createAppService/SiteNameStep.ts b/appservice/src/createAppService/SiteNameStep.ts index aac0793673..37420b310b 100644 --- a/appservice/src/createAppService/SiteNameStep.ts +++ b/appservice/src/createAppService/SiteNameStep.ts @@ -26,7 +26,7 @@ const siteNamingRules: IAzureNamingRules = { invalidCharsRegExp: /[^a-zA-Z0-9\-]/ }; -// Selecting the Tenant domain label scope actually fails if over 43 chars long, even though the CNA validation would otherwise say it's fine. +// Selecting a regional domain name label scope actually fails if over 43 chars long, even though the CNA validation would otherwise say it's fine. // Setting the limit to 43 chars seems to completely fix the issue and is the same number the portal is using. // See: https://github.com/microsoft/vscode-azuretools/pull/1882#issue-2828801875 const regionalCNAMaxLength: number = 43;