'use strict' ; import * as fs from 'fs-extra' ; import * as os from 'os' ; import * as path from 'path' ; import * as vscode from 'vscode' ; import * as semver from 'semver' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { SettingConfigurations } from '../configurations' ; import { addGateway } from '../commands/addGatewayCommand' ; import { addWallet } from '../commands/addWalletCommand' ; import { addWalletIdentity } from '../commands/addWalletIdentityCommand' ; import { associateWallet } from '../commands/associateWalletCommand' ; import { createNewIdentity } from '../commands/createNewIdentityCommand' ; import { createSmartContractProject } from '../commands/createSmartContractProjectCommand' ; import { debugCommandList } from '../commands/debugCommandListCommand' ; import { deleteGateway } from '../commands/deleteGatewayCommand' ; import { deleteIdentity } from '../commands/deleteIdentityCommand' ; import { deleteSmartContractPackage } from '../commands/deleteSmartContractPackageCommand' ; import { dissociateWallet } from '../commands/dissociateWalletCommand' ; import { exportConnectionProfile } from '../commands/exportConnectionProfileCommand' ; import { exportSmartContractPackage } from '../commands/exportSmartContractPackageCommand' ; import { exportWallet } from '../commands/exportWalletCommand' ; import { importSmartContractPackageCommand } from '../commands/importSmartContractPackageCommand' ; import { installSmartContract } from '../commands/installCommand' ; import { instantiateSmartContract } from '../commands/instantiateCommand' ; import { packageSmartContract } from '../commands/packageSmartContractCommand' ; import { removeWallet } from '../commands/removeWalletCommand' ; import { restartFabricRuntime } from '../commands/restartFabricRuntime' ; import { startFabricRuntime } from '../commands/startFabricRuntime' ; import { stopFabricRuntime } from '../commands/stopFabricRuntime' ; import { submitTransaction } from '../commands/submitTransaction' ; import { teardownFabricRuntime } from '../commands/teardownFabricRuntime' ; import { testSmartContract } from '../commands/testSmartContractCommand' ; import { upgradeSmartContract } from '../commands/upgradeCommand' ; import { FabricGoDebugConfigurationProvider } from '../debug/FabricGoDebugConfigurationProvider' ; import { FabricJavaDebugConfigurationProvider } from '../debug/FabricJavaDebugConfigurationProvider' ; import { FabricNodeDebugConfigurationProvider } from '../debug/FabricNodeDebugConfigurationProvider' ; import { BlockchainGatewayExplorerProvider } from '../explorer/gatewayExplorer' ; import { BlockchainTreeItem } from '../explorer/model/BlockchainTreeItem' ; import { ContractTreeItem } from '../explorer/model/ContractTreeItem' ; import { GatewayAssociatedTreeItem } from '../explorer/model/GatewayAssociatedTreeItem' ; import { GatewayDissociatedTreeItem } from '../explorer/model/GatewayDissociatedTreeItem' ; import { GatewayTreeItem } from '../explorer/model/GatewayTreeItem' ; import { IdentityTreeItem } from '../explorer/model/IdentityTreeItem' ; import { InstantiatedContractTreeItem } from '../explorer/model/InstantiatedContractTreeItem' ; import { InstantiatedTreeItem } from '../explorer/model/InstantiatedTreeItem' ; import { PackageTreeItem } from '../explorer/model/PackageTreeItem' ; import { TransactionTreeItem } from '../explorer/model/TransactionTreeItem' ; import { BlockchainPackageExplorerProvider } from '../explorer/packageExplorer' ; import { CertificateAuthorityTreeItem } from '../explorer/runtimeOps/connectedTree/CertificateAuthorityTreeItem' ; import { NodeTreeItem } from '../explorer/runtimeOps/connectedTree/NodeTreeItem' ; import { BlockchainWalletExplorerProvider } from '../explorer/walletExplorer' ; import { WalletTreeItem } from '../explorer/wallets/WalletTreeItem' ; import { FabricGatewayConnectionManager } from '../fabric/FabricGatewayConnectionManager' ; import { VSCodeBlockchainOutputAdapter } from '../logging/VSCodeBlockchainOutputAdapter' ; import { PackageRegistryEntry } from '../registries/PackageRegistryEntry' ; import { HomeView } from '../webview/HomeView' ; import { SampleView } from '../webview/SampleView' ; import { TutorialGalleryView } from '../webview/TutorialGalleryView' ; import { TutorialView } from '../webview/TutorialView' ; import { Fabric2View } from '../webview/Fabric2View' ; import { Reporter } from './Reporter' ; import { PreReqView } from '../webview/PreReqView' ; import { BlockchainEnvironmentExplorerProvider } from '../explorer/environmentExplorer' ; import { gatewayConnect } from '../commands/gatewayConnectCommand' ; import { addEnvironment } from '../commands/addEnvironmentCommand' ; import { FabricEnvironmentTreeItem } from '../explorer/runtimeOps/disconnectedTree/FabricEnvironmentTreeItem' ; import { deleteEnvironment } from '../commands/deleteEnvironmentCommand' ; import { associateIdentityWithNode } from '../commands/associateIdentityWithNode' ; import { fabricEnvironmentConnect } from '../commands/environmentConnectCommand' ; import { FabricEnvironmentManager } from '../fabric/environments/FabricEnvironmentManager' ; import { DependencyManager } from '../dependencies/DependencyManager' ; import { GlobalState , ExtensionData } from './GlobalState' ; import { TemporaryCommandRegistry } from '../dependencies/TemporaryCommandRegistry' ; import { version as currentExtensionVersion , dependencies } from '../../package.json' ; import { UserInputUtil } from '../commands/UserInputUtil' ; import { FabricSmartContractDefinition , FabricEnvironmentRegistry , FabricEnvironmentRegistryEntry , FabricNode , FabricRuntimeUtil , FabricWalletRegistry , FabricWalletRegistryEntry , FileRegistry , LogType , FabricGatewayRegistry , FabricGatewayRegistryEntry , EnvironmentType , EnvironmentFlags , FileSystemUtil , FileConfigurations } from 'ibm-blockchain-platform-common' ; import { importNodesToEnvironment } from '../commands/importNodesToEnvironmentCommand' ; import { deleteNode } from '../commands/deleteNodeCommand' ; import { openTransactionView } from '../commands/openTransactionViewCommand' ; import { RuntimeTreeItem } from '../explorer/runtimeOps/disconnectedTree/RuntimeTreeItem' ; import { FabricConnectionFactory } from '../fabric/FabricConnectionFactory' ; import { associateTransactionDataDirectory } from '../commands/associateTransactionDataDirectoryCommand' ; import { dissociateTransactionDataDirectory } from '../commands/dissociateTransactionDataDirectoryCommand' ; import { IAssociateFromViewOptions } from '../interfaces/IAssociateFromViewOptions' ; import { openReleaseNotes } from '../commands/openReleaseNotesCommand' ; import { viewPackageInformation } from '../commands/viewPackageInformationCommand' ; import { VSCodeBlockchainDockerOutputAdapter } from '../logging/VSCodeBlockchainDockerOutputAdapter' ; import { subscribeToEvent } from '../commands/subscribeToEventCommand' ; import { approveSmartContract } from '../commands/approveCommand' ; import { commitSmartContract } from '../commands/commitCommand' ; import { deploySmartContract } from '../commands/deployCommand' ; import { openDeployView } from '../commands/openDeployView' ; import { exportAppData } from '../commands/exportAppData' ; import { saveTutorial } from '../commands/saveTutorialCommand' ; import { manageFeatureFlags } from '../commands/manageFeatureFlags' ; import { logInAndDiscover } from '../commands/logInAndDiscoverCommand' ; import Axios from 'axios' ; import { URL } from 'url' ; import { FeatureFlagManager } from './FeatureFlags' ; import { openConsoleInBrowser } from '../commands/openConsoleInBrowserCommand' ; import { deleteExtensionDirectory } from '../commands/deleteExtensionDirectoryCommand' ; import { defaultDependencies , Dependencies } from '../dependencies/Dependencies' ; import { LocalMicroEnvironmentManager } from '../fabric/environments/LocalMicroEnvironmentManager' ; import { LocalMicroEnvironment } from '../fabric/environments/LocalMicroEnvironment' ; import { SampleGalleryView } from '../webview/SampleGalleryView' ; import { openCouchDbInBrowser } from '../commands/openCouchDbInBrowserCommand' ; let blockchainGatewayExplorerProvider ; let blockchainPackageExplorerProvider ; let blockchainEnvironmentExplorerProvider ; let blockchainWalletExplorerProvider ; export const FABRIC_NETWORK_NODE_VERSION = '2.2.0' ; export const FABRIC_NETWORK_JAVA_VERSION = '2.2.0' ; export const EXTENSION_ID = 'IBMBlockchain.ibm-blockchain-platform' ; export class ExtensionUtil { static readonly DEBUG_PACKAGE_PREFIX : string = 'vscode-debug' ; public static getPackageJSON ( ) { return this . getExtension ( ) . packageJSON ; } public static isActive ( ) { return this . getExtension ( ) . isActive ; } public static activateExtension ( ) { return this . getExtension ( ) . activate ( ) ; } public static getExtensionPath ( ) { return this . getExtension ( ) . extensionPath ; } public static async getContractNameAndVersion ( folder ) { try { const packageJson = await this . loadJSON ( folder , 'package.json' ) ; return { name : packageJson . name , version : packageJson . version } ; } catch ( error ) { return ; } } public static async loadJSON ( folder , file ) { try { const workspacePackage = path . join ( folder . uri . fsPath , file ) ; const workspacePackageContents = await fs . readFile ( workspacePackage , 'utf8' ) ; return JSON . parse ( workspacePackageContents ) ; } catch ( error ) { throw new Error ( 'error reading package.json from project ' + error . message ) ; } } public static skipNpmInstall ( ) { return false ; } public static checkIfIBMer ( ) { let isIBMer = false ; const networkInterfaces = os . networkInterfaces ( ) ; const keys = Object . keys ( networkInterfaces ) ; keys . forEach ( ( key ) => { const interfaces = networkInterfaces [ key ] ; const foundInterfaces = interfaces . filter ( ( _interface ) => { return _interface . family === 'IPv4' && _interface . address . startsWith ( '9.' ) ; } ) ; if ( foundInterfaces . length > 0 ) { isIBMer = true ; } } ) ; return isIBMer ; } public static async registerCommands ( context ) { blockchainGatewayExplorerProvider = new BlockchainGatewayExplorerProvider ( ) ; blockchainPackageExplorerProvider = new BlockchainPackageExplorerProvider ( ) ; blockchainEnvironmentExplorerProvider = new BlockchainEnvironmentExplorerProvider ( ) ; blockchainWalletExplorerProvider = new BlockchainWalletExplorerProvider ( ) ; this . disposeExtension ( context ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REFRESH_GATEWAYS , ( element ) => blockchainGatewayExplorerProvider . refresh ( element ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . CONNECT_TO_GATEWAY , ( gateway , identityName ) => gatewayConnect ( gateway , identityName ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DISCONNECT_GATEWAY , ( ) => FabricGatewayConnectionManager . instance ( ) . disconnect ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ADD_GATEWAY , ( ) => addGateway ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_GATEWAY , ( gateway ) => deleteGateway ( gateway ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ADD_WALLET_IDENTITY , ( walletItem , mspid ) => addWalletIdentity ( walletItem , mspid ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . CREATE_SMART_CONTRACT_PROJECT , ( ) => createSmartContractProject ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . PACKAGE_SMART_CONTRACT , ( workspace ? , overrideName ? , overrideVersion ? , overrideFabricVersion ? ) => packageSmartContract ( workspace , overrideName , overrideVersion , overrideFabricVersion ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REFRESH_PACKAGES , ( ) => blockchainPackageExplorerProvider . refresh ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REFRESH_ENVIRONMENTS , ( element ) => blockchainEnvironmentExplorerProvider . refresh ( element ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . START_FABRIC , ( environmentRegistryEntry ? ) => startFabricRuntime ( environmentRegistryEntry ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . START_FABRIC_SHORT , ( environmentRegistryEntry ? ) => startFabricRuntime ( environmentRegistryEntry ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . STOP_FABRIC_SHORT , ( runtimeTreeItem ? ) => stopFabricRuntime ( runtimeTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . STOP_FABRIC , ( runtimeTreeItem ? ) => stopFabricRuntime ( runtimeTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . RESTART_FABRIC , ( runtimeTreeItem ? ) => restartFabricRuntime ( runtimeTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . RESTART_FABRIC_SHORT , ( runtimeTreeItem ? ) => restartFabricRuntime ( runtimeTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . TEARDOWN_FABRIC_SHORT , ( runtimeTreeItem ? , force = false , environmentName ? , ignoreRefresh = false ) => teardownFabricRuntime ( runtimeTreeItem , force , environmentName , ignoreRefresh ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EXPORT_CONNECTION_PROFILE , ( gatewayItem , isConnected ? ) => exportConnectionProfile ( gatewayItem , isConnected ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EXPORT_CONNECTION_PROFILE_CONNECTED , ( gatewayItem , isConnected = true ) => exportConnectionProfile ( gatewayItem , isConnected ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_SMART_CONTRACT , ( project ) => deleteSmartContractPackage ( project ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EXPORT_SMART_CONTRACT , ( project ) => exportSmartContractPackage ( project ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . IMPORT_SMART_CONTRACT , ( ) => importSmartContractPackageCommand ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . VIEW_PACKAGE_INFORMATION , ( project ) => viewPackageInformation ( project ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ADD_ENVIRONMENT , ( ) => addEnvironment ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_ENVIRONMENT_SHORT , ( environmentTreeItem , force = false , ignoreRefresh = false ) => deleteEnvironment ( environmentTreeItem , force , ignoreRefresh ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE , ( environmentRegistryEntry , node ) => associateIdentityWithNode ( false , environmentRegistryEntry , node ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . IMPORT_NODES_TO_ENVIRONMENT , ( environmentRegistryEntry , fromAddEnvironment = false , createMethod = UserInputUtil . ADD_ENVIRONMENT_FROM_NODES , informOfChanges = false , showSuccess , fromConnectEnvironment ) => importNodesToEnvironment ( environmentRegistryEntry , fromAddEnvironment , createMethod , informOfChanges , showSuccess , fromConnectEnvironment ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EDIT_NODE_FILTERS , ( environmentRegistryEntry , fromAddEnvironment = false , createMethod = UserInputUtil . ADD_ENVIRONMENT_FROM_OPS_TOOLS , informOfChanges = false , showSuccess , fromConnectEnvironment ) => importNodesToEnvironment ( environmentRegistryEntry , fromAddEnvironment , createMethod , informOfChanges , showSuccess , fromConnectEnvironment ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REPLACE_ASSOCIATED_IDENTITY , async ( nodeTreeItem ) => { if ( nodeTreeItem ) { await associateIdentityWithNode ( true , nodeTreeItem . environmentRegistryEntry , nodeTreeItem . node ) ; } else { await associateIdentityWithNode ( true , undefined , undefined ) ; } } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_NODE , ( nodeTreeItem ) => deleteNode ( nodeTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . HIDE_NODE , ( nodeTreeItem ) => deleteNode ( nodeTreeItem , true ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . CONNECT_TO_ENVIRONMENT , ( fabricEnvironmentRegistryEntry , showSuccessMessage ) => fabricEnvironmentConnect ( fabricEnvironmentRegistryEntry , showSuccessMessage ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DISCONNECT_ENVIRONMENT , ( ) => FabricEnvironmentManager . instance ( ) . disconnect ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . INSTALL_SMART_CONTRACT , ( orgMap , chosenPackge ) => installSmartContract ( orgMap , chosenPackge ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . INSTANTIATE_SMART_CONTRACT , ( channelName , peerNames , selectedPackage , instantiateFunctionName , instantiateFunctionArgs , endorsementPolicy , collectionConfigString ) => instantiateSmartContract ( channelName , peerNames , selectedPackage , instantiateFunctionName , instantiateFunctionArgs , endorsementPolicy , collectionConfigString ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . APPROVE_SMART_CONTRACT , ( ordererName , channelName , orgMap , smartContractDefinition ) => approveSmartContract ( ordererName , channelName , orgMap , smartContractDefinition ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . COMMIT_SMART_CONTRACT , ( ordererName , channelName , orgMap , smartContractDefinition ) => commitSmartContract ( ordererName , channelName , orgMap , smartContractDefinition ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DEPLOY_SMART_CONTRACT , ( requireCommit , fabricEnvironmentRegistryEntry , ordererName , channelName , installApproveMap , chosenPackage , smartContractDefinition , commitMap ? ) => deploySmartContract ( requireCommit , fabricEnvironmentRegistryEntry , ordererName , channelName , installApproveMap , chosenPackage , smartContractDefinition , commitMap ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . TEST_ALL_SMART_CONTRACT , ( chaincode ) => testSmartContract ( true , chaincode ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . TEST_SMART_CONTRACT , ( treeItem ) => testSmartContract ( false , treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . SUBMIT_TRANSACTION , ( transactionTreeItem ? , channelName ? , smartContract ? , transactionObject ? ) => submitTransaction ( false , transactionTreeItem , channelName , smartContract , transactionObject ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EVALUATE_TRANSACTION , ( transactionTreeItem ? , channelName ? , smartContract ? , transactionObject ? ) => submitTransaction ( true , transactionTreeItem , channelName , smartContract , transactionObject ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . UPGRADE_SMART_CONTRACT , ( channelName , peerNames , selectedPackage , instantiateFunctionName , instantiateFunctionArgs , endorsementPolicy , collectionConfigString ) => upgradeSmartContract ( channelName , peerNames , selectedPackage , instantiateFunctionName , instantiateFunctionArgs , endorsementPolicy , collectionConfigString ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . CREATE_NEW_IDENTITY , ( certificateAuthorityTreeItem ? ) => createNewIdentity ( certificateAuthorityTreeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REFRESH_WALLETS , ( element ) => blockchainWalletExplorerProvider . refresh ( element ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ADD_WALLET , ( createIdentity , environmentGroup ? ) => addWallet ( createIdentity , environmentGroup ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DEBUG_COMMAND_LIST , ( commandName ? ) => debugCommandList ( commandName ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . REMOVE_WALLET , ( treeItem ) => removeWallet ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_IDENTITY , ( treeItem ) => deleteIdentity ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ASSOCIATE_WALLET , ( treeItem ) => associateWallet ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DISSOCIATE_WALLET , ( treeItem ) => dissociateWallet ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EXPORT_WALLET , ( treeItem ? ) => exportWallet ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . ASSOCIATE_TRANSACTION_DATA_DIRECTORY , ( treeItem , associateFromViewOptions ? ) => associateTransactionDataDirectory ( treeItem , associateFromViewOptions ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DISSOCIATE_TRANSACTION_DATA_DIRECTORY , ( treeItem ? , dissociateFromViewOptions ? ) => dissociateTransactionDataDirectory ( treeItem , dissociateFromViewOptions ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . SUBSCRIBE_TO_EVENT , ( treeItem ) => subscribeToEvent ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_DEPLOY_PAGE , ( fabricEnvironmentRegistryEntry , channelName ) => openDeployView ( fabricEnvironmentRegistryEntry , channelName ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . SAVE_TUTORIAL_AS_PDF , ( tutorialObject , saveAll ? , tutorialFolder ? ) => saveTutorial ( tutorialObject , saveAll , tutorialFolder ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . EXPORT_APP_DATA , ( treeItem ) => exportAppData ( treeItem ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . LOG_IN_AND_DISCOVER , ( ) => logInAndDiscover ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_CONSOLE_IN_BROWSER , ( environment ? ) => openConsoleInBrowser ( environment ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_DIRECTORY , ( ) => deleteExtensionDirectory ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_COUCHDB_IN_BROWSER , ( environment ? ) => openCouchDbInBrowser ( environment ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_HOME_PAGE , async ( ) => { const homeView = new HomeView ( context ) ; await homeView . openView ( true ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_SAMPLE_PAGE , async ( repoName , sampleName ) => { const sampleView = new SampleView ( context , repoName , sampleName ) ; await sampleView . openView ( false ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_TUTORIAL_GALLERY , async ( ) => { const tutorialGalleryView = new TutorialGalleryView ( context ) ; await tutorialGalleryView . openView ( true ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_SAMPLE_GALLERY , async ( ) => { const sampleGalleryView = new SampleGalleryView ( context ) ; await sampleGalleryView . openView ( true ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_TUTORIAL_PAGE , async ( seriesName , tutorialName ) => { const tutorialView = new TutorialView ( context , seriesName , tutorialName ) ; await tutorialView . openView ( true ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_FABRIC_2_PAGE , async ( ) => { const fabric2View = new Fabric2View ( context ) ; await fabric2View . openView ( true , vscode . ViewColumn . Beside ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_TRANSACTION_PAGE , ( treeItem , selectedTransactionName ) => { return openTransactionView ( treeItem , selectedTransactionName ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . MANAGE_FEATURE_FLAGS , ( ) => manageFeatureFlags ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_NEW_INSTANCE_LINK , async ( ) => { await vscode . commands . executeCommand ( 'vscode.open' , vscode . Uri . parse ( 'https://cloud.ibm.com/catalog/services/blockchain-platform' ) ) ; Reporter . instance ( ) . sendTelemetryEvent ( 'openNewInstanceLink' ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_RESOURCE_FILE , async ( relativePath ) => { const extensionPath = ExtensionUtil . getExtensionPath ( ) ; const fullPath = path . join ( extensionPath , relativePath ) ; await vscode . commands . executeCommand ( 'vscode.open' , vscode . Uri . parse ( fullPath ) ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_VSCODE_EXTENSION , async ( url = defaultDependencies . optional . ibmCloudAccountExtension . url ) => { await vscode . commands . executeCommand ( 'vscode.open' , vscode . Uri . parse ( url ) ) ; } ) ) ; const goDebugProvider = new FabricGoDebugConfigurationProvider ( ) ; const javaDebugProvider = new FabricJavaDebugConfigurationProvider ( ) ; const nodeDebugProvider = new FabricNodeDebugConfigurationProvider ( ) ; context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( 'fabric:go' , goDebugProvider ) ) ; context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( 'fabric:java' , javaDebugProvider ) ) ; context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( 'fabric:node' , nodeDebugProvider ) ) ; context . subscriptions . push ( vscode . window . registerTreeDataProvider ( 'environmentExplorer' , blockchainEnvironmentExplorerProvider ) ) ; context . subscriptions . push ( vscode . window . registerTreeDataProvider ( 'gatewaysExplorer' , blockchainGatewayExplorerProvider ) ) ; context . subscriptions . push ( vscode . window . registerTreeDataProvider ( 'aPackagesExplorer' , blockchainPackageExplorerProvider ) ) ; context . subscriptions . push ( vscode . window . registerTreeDataProvider ( 'walletExplorer' , blockchainWalletExplorerProvider ) ) ; const homePageButton = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ; homePageButton . command = ExtensionCommands . OPEN_HOME_PAGE ; homePageButton . text = 'Blockchain Home' ; homePageButton . tooltip = 'View Homepage' ; context . subscriptions . push ( homePageButton ) ; homePageButton . show ( ) ; FabricWalletRegistry . instance ( ) . on ( FileRegistry . EVENT_NAME , ( async ( ) : Promise < void > => { try { await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_WALLETS ) ; } catch ( error ) { } } ) ) ; FabricGatewayRegistry . instance ( ) . on ( FileRegistry . EVENT_NAME , ( async ( ) : Promise < void > => { try { await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_GATEWAYS ) ; } catch ( error ) { } } ) ) ; FabricEnvironmentRegistry . instance ( ) . on ( FileRegistry . EVENT_NAME , ( async ( ) : Promise < void > => { try { await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_GATEWAYS ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_WALLETS ) ; } catch ( error ) { } } ) ) ; context . subscriptions . push ( vscode . workspace . onDidChangeConfiguration ( async ( e ) => { if ( e . affectsConfiguration ( SettingConfigurations . EXTENSION_LOCAL_FABRIC ) ) { const runtimeManager = LocalMicroEnvironmentManager . instance ( ) ; const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; const localFabricEnabled = ExtensionUtil . getExtensionLocalFabricSetting ( ) ; if ( ExtensionUtil . isChe ( ) ) { if ( localFabricEnabled ) { outputAdapter . log ( LogType . ERROR , 'Local Fabric functionality is not supported in Eclipse Che or Red Hat CodeReady Workspaces.' ) ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_LOCAL_FABRIC , false , vscode . ConfigurationTarget . Global ) ; } return ; } const runtimes = [ ] ; const environmentEntries = await FabricEnvironmentRegistry . instance ( ) . getAll ( [ EnvironmentFlags . LOCAL ] ) ; for ( const entry of environmentEntries ) { const _runtime = await LocalMicroEnvironmentManager . instance ( ) . ensureRuntime ( entry . name , undefined , entry . numberOfOrgs ) ; runtimes . push ( _runtime ) ; } if ( ! localFabricEnabled ) { try { if ( runtimes . length > 0 ) { const reallyDoIt = await UserInputUtil . showConfirmationWarningMessage ( `Toggling this feature will remove the world state and ledger data for all local runtimes. Do you want to continue?` ) ; if ( ! reallyDoIt ) { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_LOCAL_FABRIC , true , vscode . ConfigurationTarget . Global ) ; return ; } for ( const runtime of runtimes ) { const runtimeName = runtime . getName ( ) ; try { await vscode . commands . executeCommand ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , runtimeName ) ; } catch ( err ) { } await FabricEnvironmentRegistry . instance ( ) . delete ( runtimeName , true ) ; runtimeManager . removeRuntime ( runtimeName ) ; } } await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , false ) ; } catch ( error ) { outputAdapter . log ( LogType . ERROR , `Error whilst toggling local Fabric functionality to false: ${ error . message }` , `Error whilst toggling local Fabric functionality to false: ${ error . toString ( ) }` ) ; } } else { try { const bypassPreReqs = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_BYPASS_PREREQS ) ; let dependenciesInstalled = true ; if ( ! bypassPreReqs ) { const dependencyManager = DependencyManager . instance ( ) ; dependenciesInstalled = await dependencyManager . hasPreReqsInstalled ( ) ; if ( ! dependenciesInstalled ) { const ctx = GlobalState . getExtensionContext ( ) ; this . disposeExtension ( ctx ) ; await this . registerPreActivationCommands ( ctx ) ; const tempCommandRegistry = TemporaryCommandRegistry . instance ( ) ; tempCommandRegistry . createTempCommands ( false , ExtensionCommands . OPEN_PRE_REQ_PAGE ) ; await vscode . commands . executeCommand ( ExtensionCommands . OPEN_PRE_REQ_PAGE ) ; return ; } } await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , true ) ; } catch ( error ) { outputAdapter . log ( LogType . ERROR , `Error whilst toggling local Fabric functionality to true: ${ error . message }` , `Error whilst toggling local Fabric functionality to true: ${ error . toString ( ) }` ) ; } } const extensionData = GlobalState . get ( ) ; if ( localFabricEnabled && ! extensionData . deletedOneOrgLocalFabric ) { const localRuntime = LocalMicroEnvironmentManager . instance ( ) . getRuntime ( FabricRuntimeUtil . LOCAL_FABRIC ) ; if ( ! localRuntime ) { outputAdapter . log ( LogType . INFO , undefined , 'Initializing local runtime manager' ) ; try { await runtimeManager . initialize ( FabricRuntimeUtil . LOCAL_FABRIC , 1 ) ; extensionData . createOneOrgLocalFabric = false ; await GlobalState . update ( extensionData ) ; } catch ( error ) { outputAdapter . log ( LogType . ERROR , `Error initializing ${ FabricRuntimeUtil . LOCAL_FABRIC }: ${ error . message }` , `Error initializing ${ FabricRuntimeUtil . LOCAL_FABRIC }: ${ error . toString ( ) }` ) ; } } } await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_GATEWAYS ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_WALLETS ) ; } } ) ) ; let connectedRuntime ; FabricEnvironmentManager . instance ( ) . on ( 'connected' , async ( ) => { const registryEntry = FabricEnvironmentManager . instance ( ) . getEnvironmentRegistryEntry ( ) ; if ( registryEntry . environmentType === EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ) { connectedRuntime = LocalMicroEnvironmentManager . instance ( ) . getRuntime ( registryEntry . name ) ; const outputAdapter = VSCodeBlockchainDockerOutputAdapter . instance ( registryEntry . name ) ; connectedRuntime . startLogs ( outputAdapter ) ; } else { connectedRuntime = undefined ; } } ) ; FabricEnvironmentManager . instance ( ) . on ( 'disconnected' , async ( ) => { if ( connectedRuntime instanceof LocalMicroEnvironment ) { connectedRuntime . stopLogs ( ) ; connectedRuntime = undefined ; } } ) ; context = await this . registerPreActivationCommands ( context ) ; const packageJson = ExtensionUtil . getPackageJSON ( ) ; if ( packageJson . production === true ) { context . subscriptions . push ( Reporter . instance ( ) ) ; } return context ; } public static async setupLocalRuntime ( ) { const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . INFO , undefined , 'Initializing local runtime manager' ) ; await LocalMicroEnvironmentManager . instance ( ) . initialize ( FabricRuntimeUtil . LOCAL_FABRIC , 1 ) ; } public static async setupCommands ( ) { const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; const dependencyManager = DependencyManager . instance ( ) ; outputAdapter . log ( LogType . INFO , undefined , 'Clearing extension cache' ) ; await dependencyManager . clearExtensionCache ( ) ; const extensionData = GlobalState . get ( ) ; const localFabricEnabled = this . getExtensionLocalFabricSetting ( ) ; const tempCommandRegistry = TemporaryCommandRegistry . instance ( ) ; outputAdapter . log ( LogType . INFO , undefined , 'Restoring command registry' ) ; tempCommandRegistry . restoreCommands ( ) ; FabricConnectionFactory . createFabricWallet ( ) ; outputAdapter . log ( LogType . INFO , undefined , 'Registering commands' ) ; const context = GlobalState . getExtensionContext ( ) ; await ExtensionUtil . registerCommands ( context ) ; if ( localFabricEnabled ) { if ( extensionData . createOneOrgLocalFabric ) { await ExtensionUtil . setupLocalRuntime ( ) ; extensionData . createOneOrgLocalFabric = false ; await GlobalState . update ( extensionData ) ; } } else { await FabricEnvironmentRegistry . instance ( ) . delete ( FabricRuntimeUtil . LOCAL_FABRIC , true ) ; LocalMicroEnvironmentManager . instance ( ) . removeRuntime ( FabricRuntimeUtil . LOCAL_FABRIC ) ; } outputAdapter . log ( LogType . INFO , undefined , 'Execute stored commands in the registry' ) ; await tempCommandRegistry . executeStoredCommands ( ) ; } public static async completeActivation ( extensionUpdated ? ) { const outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; const extensionData = GlobalState . get ( ) ; if ( extensionUpdated === undefined ) { extensionUpdated = currentExtensionVersion !== extensionData . version ; } if ( extensionUpdated ) { outputAdapter . log ( LogType . INFO , 'IBM Blockchain Platform Extension activated' ) ; } else { outputAdapter . log ( LogType . INFO , null , 'IBM Blockchain Platform Extension activated' ) ; } const showPage = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . HOME_SHOW_ON_STARTUP ) ; const showPageNext = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . HOME_SHOW_ON_NEXT_ACTIVATION ) ; if ( showPageNext || ( extensionUpdated && showPage ) ) { await vscode . commands . executeCommand ( ExtensionCommands . OPEN_HOME_PAGE ) ; if ( showPageNext ) { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . HOME_SHOW_ON_NEXT_ACTIVATION , false , vscode . ConfigurationTarget . Global ) ; } } const generatorVersion = dependencies [ 'generator-fabric' ] ; if ( extensionData . generatorVersion && generatorVersion !== extensionData . generatorVersion ) { let teardownRuntimes = false ; let updateGeneratorVersion = true ; const envEntries = await FabricEnvironmentRegistry . instance ( ) . getAll ( [ EnvironmentFlags . LOCAL ] ) ; if ( envEntries . length > 0 ) { const runtimeManager = LocalMicroEnvironmentManager . instance ( ) ; const runtimes = [ ] ; for ( const entry of envEntries ) { const localRuntime = await runtimeManager . ensureRuntime ( entry . name , undefined , entry . numberOfOrgs ) ; runtimes . push ( localRuntime ) ; } const generatorSemver = semver . coerce ( generatorVersion ) ; const storedSemver = semver . coerce ( extensionData . generatorVersion ) ; const generatorMajor = generatorSemver . major ; const storedMajor = storedSemver . major ; if ( generatorMajor > storedMajor ) { teardownRuntimes = true ; } if ( ! teardownRuntimes ) { teardownRuntimes = await UserInputUtil . showConfirmationWarningMessage ( `The local runtime configurations are out of date and must be torn down before updating. Do you want to teardown your local runtimes now?` ) ; } else { outputAdapter . log ( LogType . IMPORTANT , `A major version of the generator has been released. All local runtimes will be torn down.` ) ; } if ( teardownRuntimes ) { for ( const runtime of runtimes ) { const created = await runtime . isCreated ( ) ; const runtimeName = runtime . getName ( ) ; if ( created ) { const isRunning = await runtime . isRunning ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , runtimeName ) ; if ( isRunning ) { const envEntry = envEntries . find ( ( env ) => { return env . name === runtime . getName ( ) ; } ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC , envEntry ) ; } } } } else { updateGeneratorVersion = false ; } } if ( updateGeneratorVersion ) { extensionData . generatorVersion = generatorVersion ; await GlobalState . update ( extensionData ) ; } } const localFabricEnabled = this . getExtensionLocalFabricSetting ( ) ; if ( localFabricEnabled ) { await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , true ) ; } else { await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , false ) ; } const features = await FeatureFlagManager . get ( ) ; for ( const feature of FeatureFlagManager . ALL ) { const hasContext = feature . getContext ( ) ; if ( hasContext ) { if ( ! ! features [ feature . getName ( ) ] ) { await vscode . commands . executeCommand ( 'setContext' , feature . getName ( ) , true ) ; } else { await vscode . commands . executeCommand ( 'setContext' , feature . getName ( ) , false ) ; } } } if ( ! extensionData . generatorVersion ) { extensionData . generatorVersion = generatorVersion ; await GlobalState . update ( extensionData ) ; } await this . discoverEnvironments ( ) ; } public static getBlockchainGatewayExplorerProvider ( ) { return blockchainGatewayExplorerProvider ; } public static getBlockchainEnvironmentExplorerProvider ( ) { return blockchainEnvironmentExplorerProvider ; } public static getBlockchainPackageExplorerProvider ( ) { return blockchainPackageExplorerProvider ; } public static getBlockchainWalletExplorerProvider ( ) { return blockchainWalletExplorerProvider ; } public static disposeExtension ( context ) { context . subscriptions . forEach ( ( item ) => { if ( item ) { item . dispose ( ) ; } } ) ; context . subscriptions . splice ( 0 , context . subscriptions . length ) ; } public static async registerPreActivationCommands ( context ) { context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_PRE_REQ_PAGE , async ( d ) => { const preReqView = new PreReqView ( context , d ) ; await preReqView . openView ( true ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . OPEN_RELEASE_NOTES , ( ) => openReleaseNotes ( ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . DELETE_ENVIRONMENT , ( environmentTreeItem , force = false , ignoreRefresh = false ) => deleteEnvironment ( environmentTreeItem , force , ignoreRefresh ) ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( ExtensionCommands . TEARDOWN_FABRIC , ( runtimeTreeItem ? , force = false , environmentName ? , ignoreRefresh = false ) => teardownFabricRuntime ( runtimeTreeItem , force , environmentName , ignoreRefresh ) ) ) ; return context ; } public static getExtensionLocalFabricSetting ( ) { return vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_LOCAL_FABRIC ) ; } public static getExtensionSaasConfigUpdatesSetting ( ) { return vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_SAAS_CONFIG_UPDATES ) ; } public static async discoverEnvironments ( ) { if ( ExtensionUtil . isChe ( ) ) { await this . discoverCheEnvironments ( ) ; } } public static async discoverCheEnvironments ( ) { const MICROFAB_SERVICE_HOST = process . env [ 'MICROFAB_SERVICE_HOST' ] ; const MICROFAB_SERVICE_PORT = process . env [ 'MICROFAB_SERVICE_PORT' ] ; if ( ! MICROFAB_SERVICE_HOST || ! MICROFAB_SERVICE_PORT ) { return ; } const url = `http://${ MICROFAB_SERVICE_HOST }:${ MICROFAB_SERVICE_PORT }` ; try { await Axios . get ( new URL ( '/ak/api/v1/health' , url ) . toString ( ) ) ; } catch ( error ) { return ; } const extensionDirectory = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_DIRECTORY ) ; const resolvedExtensionDirectory = FileSystemUtil . getDirPath ( extensionDirectory ) ; const environmentDirectory = path . join ( resolvedExtensionDirectory , FileConfigurations . FABRIC_ENVIRONMENTS , 'Microfab' ) ; const environmentRegistry = FabricEnvironmentRegistry . instance ( ) ; const environmentExists = await environmentRegistry . exists ( 'Microfab' ) ; const environmentRegistryEntry = new FabricEnvironmentRegistryEntry ( { name : 'Microfab' , managedRuntime : false , environmentType : EnvironmentType . MICROFAB_ENVIRONMENT , environmentDirectory , url } ) ; if ( ! environmentExists ) { await environmentRegistry . add ( environmentRegistryEntry ) ; } else { await environmentRegistry . update ( environmentRegistryEntry ) ; } } /**
     * In VS Code 1.53 and greater, executeCommand handles errors differently and does not bubble thrown errors from the command code back up.
     *
     * The executeCommand function now displays it's own error, e.g "Running the contributed command:'environmentExplorer.approveSmartContractEntry' failed"
     *
     * Now, we should return errors in addition to using this function to handle them.
     */ public static async executeCommandInternal ( command , ... args ) { const result = await vscode . commands . executeCommand ( command , ... args ) ; if ( result instanceof Error ) { throw result ; } return result ; } public static isChe ( ) { return 'CHE_WORKSPACE_ID' in process . env ; } private static getExtension ( ) { return vscode . extensions . getExtension ( EXTENSION_ID ) ; } }