import * as vscode from 'vscode' ; import { Utils } from 'vscode-uri' ; import { ExecuteCommandParams , ExecuteCommandRequest } from 'vscode-languageclient' ; import { ClientHandler } from '../clientHandler' ; import { getActiveTextEditor , isTerraformFile } from '../vscodeUtils' ; interface ModuleProvidersResponse { v : number ; provider_requirements : { [ provider ] : { display_name : string ; version_constraint ? : string ; docs_link ? : string ; } ; } ; installed_providers : { [ provider ] : string ; } ; } class ModuleProviderItem extends vscode . TreeItem { constructor ( public fullName , public displayName , public requiredVersion , public installedVersion , public docsLink ) { super ( displayName , vscode . TreeItemCollapsibleState . None ) ; this . description = installedVersion ?? '' ; this . iconPath = new vscode . ThemeIcon ( 'package' ) ; this . tooltip = `${ fullName } ${ requiredVersion ?? '' }` ; if ( docsLink ) { this . contextValue = 'moduleProviderHasDocs' ; } } } export class ModuleProvidersDataProvider implements vscode . TreeDataProvider < ModuleProviderItem > { private readonly didChangeTreeData = new vscode . EventEmitter < void | ModuleProviderItem > ( ) ; public readonly onDidChangeTreeData = this . didChangeTreeData . event ; constructor ( ctx , private handler ) { ctx . subscriptions . push ( vscode . window . onDidChangeActiveTextEditor ( async ( event ) => { const activeEditor = getActiveTextEditor ( ) ; if ( ! isTerraformFile ( activeEditor ?. document ) ) { return ; } if ( event && activeEditor ) { this . refresh ( ) ; } } ) , vscode . commands . registerCommand ( 'terraform.providers.openDocumentation' , ( module ) => { if ( module . docsLink ) { vscode . env . openExternal ( vscode . Uri . parse ( module . docsLink ) ) ; } } ) ) ; } refresh ( ) { this . didChangeTreeData . fire ( ) ; } getTreeItem ( element ) { return element ; } getChildren ( element ? ) { if ( element ) { return [ ] ; } else { return this . getProvider ( ) ; } } async getProvider ( ) { const activeEditor = getActiveTextEditor ( ) ; if ( activeEditor ?. document === undefined ) { return [ ] ; } if ( ! isTerraformFile ( activeEditor . document ) ) { return [ ] ; } const editor = activeEditor . document . uri ; const documentURI = Utils . dirname ( editor ) ; const handler = this . handler . getClient ( ) ; if ( handler === undefined ) { return [ ] ; } await handler . client . onReady ( ) ; const moduleCallsSupported = this . handler . clientSupportsCommand ( `${ handler . commandPrefix }.terraform-ls.module.providers` ) ; if ( ! moduleCallsSupported ) { return [ ] ; } const params = { command : `${ handler . commandPrefix }.terraform-ls.module.providers` , arguments : [ `uri=${ documentURI }` ] , } ; const response = await handler . client . sendRequest < ExecuteCommandParams , ModuleProvidersResponse , void > ( ExecuteCommandRequest . type , params ) ; if ( response === null ) { return [ ] ; } return Object . entries ( response . provider_requirements ) . map ( ( [ provider , details ] ) => new ModuleProviderItem ( provider , details . display_name , details . version_constraint , response . installed_providers [ provider ] , details . docs_link ) ) . filter ( ( m ) => Boolean ( m . requiredVersion ) ) ; } }