import type { WebSiteManagementClient , WebSiteManagementModels } from '@azure/arm-appservice' ; import { AzureNameStep , IAzureNamingRules , ResourceGroupListStep , resourceGroupNamingRules , StorageAccountListStep , storageAccountNamingRules } from 'vscode-azureextensionui' ; import { localize } from '../localize' ; import { createWebSiteClient } from '../utils/azureClients' ; import { appInsightsNamingRules } from './AppInsightsListStep' ; import { AppKind } from './AppKind' ; import { AppServicePlanListStep } from './AppServicePlanListStep' ; import { appServicePlanNamingRules } from './AppServicePlanNameStep' ; import { IAppServiceWizardContext } from './IAppServiceWizardContext' ; const siteNamingRules = { minLength : 2 , maxLength : 60 , invalidCharsRegExp : /[^a-zA-Z0-9\-]/ } ; export class SiteNameStep extends AzureNameStep < IAppServiceWizardContext > { public async prompt ( context ) { const client = await createWebSiteClient ( context ) ; let placeHolder ; if ( context . environment . name === 'Azure' ) { let namePlaceholder ; if ( context . newSiteKind === AppKind . functionapp ) { namePlaceholder = localize ( 'funcAppName' , 'function app name' ) ; } else if ( context . newSiteKind ?. includes ( AppKind . workflowapp ) ) { namePlaceholder = localize ( 'logicAppName' , 'logic app name' ) ; } else { namePlaceholder = localize ( 'webAppName' , 'web app name' ) ; } placeHolder = `<${ namePlaceholder }>.azurewebsites.net` ; } let prompt ; if ( context . newSiteKind === AppKind . functionapp ) { prompt = localize ( 'functionAppNamePrompt' , 'Enter a globally unique name for the new function app.' ) ; } else if ( context . newSiteKind ?. includes ( AppKind . workflowapp ) ) { prompt = localize ( 'functionAppNamePrompt' , 'Enter a globally unique name for the new logic app.' ) ; } else { prompt = localize ( 'webAppNamePrompt' , 'Enter a globally unique name for the new web app.' ) ; } context . newSiteName = ( await context . ui . showInputBox ( { prompt , placeHolder , validateInput : async ( name ) : Promise < string | undefined > => await this . validateSiteName ( client , name ) } ) ) . trim ( ) ; context . valuesToMask . push ( context . newSiteName ) ; const namingRules = [ resourceGroupNamingRules ] ; if ( context . newSiteKind === AppKind . functionapp ) { namingRules . push ( storageAccountNamingRules ) ; } else { namingRules . push ( appServicePlanNamingRules ) ; } namingRules . push ( appInsightsNamingRules ) ; context . relatedNameTask = this . generateRelatedName ( context , context . newSiteName , namingRules ) ; } public async getRelatedName ( context , name ) { return await this . generateRelatedName ( context , name , appServicePlanNamingRules ) ; } public shouldPrompt ( context ) { return ! context . newSiteName ; } protected async isRelatedNameAvailable ( context , name ) { const tasks = [ ResourceGroupListStep . isNameAvailable ( context , name ) ] ; if ( context . newSiteKind === AppKind . functionapp ) { tasks . push ( StorageAccountListStep . isNameAvailable ( context , name ) ) ; } else { tasks . push ( AppServicePlanListStep . isNameAvailable ( context , name , name ) ) ; } return ( await Promise . all ( tasks ) ) . every ( ( v ) => v ) ; } private async validateSiteName ( client , name ) { name = name . trim ( ) ; if ( name . length < siteNamingRules . minLength || name . length > siteNamingRules . maxLength ) { return localize ( 'invalidLength' , 'The name must be between {0} and {1} characters.' , siteNamingRules . minLength , siteNamingRules . maxLength ) ; } else if ( siteNamingRules . invalidCharsRegExp . test ( name ) ) { return localize ( 'invalidChars' , "The name can only contain letters, numbers, or hyphens." ) ; } else { const nameAvailability = await client . checkNameAvailability ( name , 'Site' ) ; if ( ! nameAvailability . nameAvailable ) { return nameAvailability . message ; } else { return undefined ; } } } }