import * as path from 'path' ; import { isNullOrUndefined } from 'util' ; import { ConfigurationTarget , Uri } from 'vscode' ; import { configKeys } from '../../../common' ; import { normalizeFilePath } from '../../util/normalizedPaths' ; import { IConfiguration } from '../../vscodeIntegration/Configuration' ; import { getRelativeParameterFilePath , resolveParameterFilePath } from './parameterFilePaths' ; interface IMapping { resolvedTemplate : Uri ; normalizedTemplate : Uri ; resolvedParams : Uri ; normalizedParams : Uri ; } export class DeploymentFileMapping { private _mapToParams : Map < string , IMapping > | undefined ; private _mapToTemplates : Map < string , IMapping > | undefined ; public constructor ( private configuration ) { } public resetCache ( ) { this . _mapToParams = undefined ; this . _mapToTemplates = undefined ; } private ensureMapsCreated ( ) { if ( this . _mapToParams && this . _mapToTemplates ) { return ; } this . _mapToParams = new Map < string , IMapping > ( ) ; this . _mapToTemplates = new Map < string , IMapping > ( ) ; const paramFiles = this . configuration . get < { [ key ] : unknown ; } > ( configKeys . parameterFiles ) || { } ; if ( typeof paramFiles === 'object' ) { for ( let templatePath of Object . getOwnPropertyNames ( paramFiles ) ) { let paramPathObject = paramFiles [ templatePath ] ; if ( typeof paramPathObject !== 'string' || isNullOrUndefined ( paramPathObject ) ) { continue ; } const paramPath = < string > paramPathObject ; const resolvedTemplatePath = path . resolve ( templatePath ) ; const normalizedTemplatePath = normalizeFilePath ( resolvedTemplatePath ) ; if ( path . isAbsolute ( templatePath ) && isFilePath ( templatePath ) ) { let resolvedParamPath = resolveParameterFilePath ( normalizedTemplatePath , paramPath ) ; if ( isFilePath ( resolvedParamPath ) ) { this . _mapToParams . set ( normalizedTemplatePath , { resolvedTemplate : Uri . file ( resolvedTemplatePath ) , normalizedTemplate : Uri . file ( normalizedTemplatePath ) , resolvedParams : Uri . file ( resolvedParamPath ) , normalizedParams : Uri . file ( normalizeFilePath ( resolvedParamPath ) ) } ) ; } } } } for ( let entry of this . _mapToParams ) { const mapping = entry [ 1 ] ; this . _mapToTemplates . set ( mapping . normalizedParams . fsPath , mapping ) ; } } /**
     * Given a template file, find the parameter file, if any, that the user currently has associated with it.
     */ public getParameterFile ( templateFileUri ) { this . ensureMapsCreated ( ) ; const normalizedTemplatePath = normalizeFilePath ( templateFileUri ) ; const entry = this . _mapToParams ?. get ( normalizedTemplatePath ) ; return entry ?. resolvedParams ; } /**
     * Given a parameter file, find the template file, if any, that the user currently has associated with it.
     */ public getTemplateFile ( parameterFileUri ) { this . ensureMapsCreated ( ) ; const normalizedParamPath = normalizeFilePath ( parameterFileUri ) ; const entry = this . _mapToTemplates ?. get ( normalizedParamPath ) ; return entry ?. resolvedTemplate ; } /**
     * Sets a mapping from a template file to a parameter file
     */ public async mapParameterFile ( templateUri , paramFileUri ) { const relativeParamFilePath = paramFileUri ? getRelativeParameterFilePath ( templateUri , paramFileUri ) : undefined ; const normalizedTemplatePath = normalizeFilePath ( templateUri . fsPath ) ; let map = this . configuration . inspect < { [ key ] : string | undefined ; } > ( configKeys . parameterFiles ) ?. globalValue || { } ; if ( typeof map !== 'object' ) { map = { } ; } const newMap = { } ; for ( let templatePath of Object . getOwnPropertyNames ( map ) ) { if ( normalizeFilePath ( templatePath ) !== normalizedTemplatePath ) { newMap [ templatePath ] = map [ templatePath ] ; } } if ( paramFileUri ) { newMap [ normalizedTemplatePath ] = relativeParamFilePath ; } await this . configuration . update ( configKeys . parameterFiles , newMap , ConfigurationTarget . Global ) ; this . resetCache ( ) ; } } function isFilePath ( p ) { const resolved = path . resolve ( p ) ; return ! ! resolved . match ( /[^./\\]/ ) ; }