UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

253 lines (249 loc) 13.7 kB
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6'; import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls'; import { ExtHostContext, CandidatePortSource, MainContext } from '@codingame/monaco-vscode-api/vscode/vs/workbench/api/common/extHost.protocol'; import { TunnelDtoConverter } from '@codingame/monaco-vscode-api/vscode/vs/workbench/api/common/extHostTunnelService'; import { extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js'; import { PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, PortsEnablement, PORT_AUTO_SOURCE_SETTING_HYBRID } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteExplorerService'; import { IRemoteExplorerService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteExplorerService.service'; import { TunnelProtocol } from '@codingame/monaco-vscode-api/vscode/vs/platform/tunnel/common/tunnel'; import { ITunnelService } from '@codingame/monaco-vscode-api/vscode/vs/platform/tunnel/common/tunnel.service'; import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle'; import '@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/notification'; import { INotificationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/notification.service'; import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service'; import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service'; import { IRemoteAgentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteAgentService.service'; import { Registry } from '@codingame/monaco-vscode-api/vscode/vs/platform/registry/common/platform'; import { Extensions } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configurationRegistry'; import { IContextKeyService } from '@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service'; import { TunnelSource, TunnelCloseReason, makeAddress, forwardedPortsFeaturesEnabled } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/tunnelModel'; import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity'; let MainThreadTunnelService = class MainThreadTunnelService extends Disposable { constructor( extHostContext, remoteExplorerService, tunnelService, notificationService, configurationService, logService, remoteAgentService, contextKeyService ) { super(); this.remoteExplorerService = remoteExplorerService; this.tunnelService = tunnelService; this.notificationService = notificationService; this.configurationService = configurationService; this.logService = logService; this.remoteAgentService = remoteAgentService; this.contextKeyService = contextKeyService; this.elevateionRetry = false; this.portsAttributesProviders = ( new Map()); this._alreadyRegistered = false; this._proxy = ( extHostContext.getProxy(ExtHostContext.ExtHostTunnelService)); this._register(tunnelService.onTunnelOpened(() => this._proxy.$onDidTunnelsChange())); this._register(tunnelService.onTunnelClosed(() => this._proxy.$onDidTunnelsChange())); } processFindingEnabled() { return (!!this.configurationService.getValue(PORT_AUTO_FORWARD_SETTING) || this.tunnelService.hasTunnelProvider) && (this.configurationService.getValue(PORT_AUTO_SOURCE_SETTING) !== PORT_AUTO_SOURCE_SETTING_OUTPUT); } async $setRemoteTunnelService(processId) { this.remoteExplorerService.namedProcesses.set(processId, "Code Extension Host"); if (this.remoteExplorerService.portsFeaturesEnabled === PortsEnablement.AdditionalFeatures) { this._proxy.$registerCandidateFinder(this.processFindingEnabled()); } else { this._register( this.remoteExplorerService.onEnabledPortsFeatures(() => this._proxy.$registerCandidateFinder(this.processFindingEnabled())) ); } this._register(this.configurationService.onDidChangeConfiguration(async e => { if ((this.remoteExplorerService.portsFeaturesEnabled === PortsEnablement.AdditionalFeatures) && (e.affectsConfiguration(PORT_AUTO_FORWARD_SETTING) || e.affectsConfiguration(PORT_AUTO_SOURCE_SETTING))) { return this._proxy.$registerCandidateFinder(this.processFindingEnabled()); } })); this._register(this.tunnelService.onAddedTunnelProvider(async () => { if (this.remoteExplorerService.portsFeaturesEnabled === PortsEnablement.AdditionalFeatures) { return this._proxy.$registerCandidateFinder(this.processFindingEnabled()); } })); } async $registerPortsAttributesProvider(selector, providerHandle) { this.portsAttributesProviders.set(providerHandle, selector); if (!this._alreadyRegistered) { this.remoteExplorerService.tunnelModel.addAttributesProvider(this); this._alreadyRegistered = true; } } async $unregisterPortsAttributesProvider(providerHandle) { this.portsAttributesProviders.delete(providerHandle); } async providePortAttributes(ports, pid, commandLine, token) { if (this.portsAttributesProviders.size === 0) { return []; } const appropriateHandles = ( Array.from(this.portsAttributesProviders.entries()).filter(entry => { const selector = entry[1]; const portRange = (typeof selector.portRange === "number") ? [selector.portRange, selector.portRange + 1] : selector.portRange; const portInRange = portRange ? ( ports.some(port => portRange[0] <= port && port < portRange[1])) : true; const commandMatches = !selector.commandPattern || (commandLine && (commandLine.match(selector.commandPattern))); return portInRange && commandMatches; }).map(entry => entry[0])); if (appropriateHandles.length === 0) { return []; } return this._proxy.$providePortAttributes(appropriateHandles, ports, pid, commandLine, token); } async $openTunnel(tunnelOptions, source) { const tunnel = await this.remoteExplorerService.forward({ remote: tunnelOptions.remoteAddress, local: tunnelOptions.localAddressPort, name: tunnelOptions.label, source: { source: TunnelSource.Extension, description: source }, elevateIfNeeded: false }); if (!tunnel || (typeof tunnel === "string")) { return undefined; } if (!this.elevateionRetry && (tunnelOptions.localAddressPort !== undefined) && (tunnel.tunnelLocalPort !== undefined) && this.tunnelService.isPortPrivileged(tunnelOptions.localAddressPort) && (tunnel.tunnelLocalPort !== tunnelOptions.localAddressPort) && this.tunnelService.canElevate) { this.elevationPrompt(tunnelOptions, tunnel, source); } return TunnelDtoConverter.fromServiceTunnel(tunnel); } async elevationPrompt(tunnelOptions, tunnel, source) { return this.notificationService.prompt(Severity.Info, ( localize( 2644, "The extension {0} has forwarded port {1}. You'll need to run as superuser to use port {2} locally.", source, tunnelOptions.remoteAddress.port, tunnelOptions.localAddressPort )), [{ label: ( localize(2645, "Use Port {0} as Sudo...", tunnel.tunnelRemotePort)), run: async () => { this.elevateionRetry = true; await this.remoteExplorerService.close({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort }, TunnelCloseReason.Other); await this.remoteExplorerService.forward({ remote: tunnelOptions.remoteAddress, local: tunnelOptions.localAddressPort, name: tunnelOptions.label, source: { source: TunnelSource.Extension, description: source }, elevateIfNeeded: true }); this.elevateionRetry = false; } }]); } async $closeTunnel(remote) { return this.remoteExplorerService.close(remote, TunnelCloseReason.Other); } async $getTunnels() { return ( (await this.tunnelService.tunnels).map(tunnel => { return { remoteAddress: { port: tunnel.tunnelRemotePort, host: tunnel.tunnelRemoteHost }, localAddress: tunnel.localAddress, privacy: tunnel.privacy, protocol: tunnel.protocol }; })); } async $onFoundNewCandidates(candidates) { this.remoteExplorerService.onFoundNewCandidates(candidates); } async $setTunnelProvider(features, isResolver) { const tunnelProvider = { forwardPort: (tunnelOptions, tunnelCreationOptions) => { const forward = this._proxy.$forwardPort(tunnelOptions, tunnelCreationOptions); return forward.then(tunnelOrError => { if (!tunnelOrError) { return undefined; } else if (typeof tunnelOrError === "string") { return tunnelOrError; } const tunnel = tunnelOrError; this.logService.trace( `ForwardedPorts: (MainThreadTunnelService) New tunnel established by tunnel provider: ${tunnel?.remoteAddress.host}:${tunnel?.remoteAddress.port}` ); return { tunnelRemotePort: tunnel.remoteAddress.port, tunnelRemoteHost: tunnel.remoteAddress.host, localAddress: typeof tunnel.localAddress === "string" ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port), tunnelLocalPort: typeof tunnel.localAddress !== "string" ? tunnel.localAddress.port : undefined, public: tunnel.public, privacy: tunnel.privacy, protocol: tunnel.protocol ?? TunnelProtocol.Http, dispose: async silent => { this.logService.trace( `ForwardedPorts: (MainThreadTunnelService) Closing tunnel from tunnel provider: ${tunnel?.remoteAddress.host}:${tunnel?.remoteAddress.port}` ); return this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port }, silent); } }; }); } }; if (features) { this.tunnelService.setTunnelFeatures(features); } this.tunnelService.setTunnelProvider(tunnelProvider); if (isResolver) { this.contextKeyService.createKey(forwardedPortsFeaturesEnabled.key, true); } } async $hasTunnelProvider() { return this.tunnelService.hasTunnelProvider; } async $setCandidateFilter() { this.remoteExplorerService.setCandidateFilter(candidates => { return this._proxy.$applyCandidateFilter(candidates); }); } async $setCandidatePortSource(source) { this.remoteAgentService.getEnvironment().then(() => { switch (source) { case CandidatePortSource.None: { ( Registry.as(Extensions.Configuration)).registerDefaultConfigurations([{ overrides: { "remote.autoForwardPorts": false } }]); break; } case CandidatePortSource.Output: { ( Registry.as(Extensions.Configuration)).registerDefaultConfigurations([{ overrides: { "remote.autoForwardPortsSource": PORT_AUTO_SOURCE_SETTING_OUTPUT } }]); break; } case CandidatePortSource.Hybrid: { ( Registry.as(Extensions.Configuration)).registerDefaultConfigurations([{ overrides: { "remote.autoForwardPortsSource": PORT_AUTO_SOURCE_SETTING_HYBRID } }]); break; } } }).catch(() => {}); } }; MainThreadTunnelService = __decorate([extHostNamedCustomer(MainContext.MainThreadTunnelService), ( __param(1, IRemoteExplorerService)), ( __param(2, ITunnelService)), ( __param(3, INotificationService)), ( __param(4, IConfigurationService)), ( __param(5, ILogService)), ( __param(6, IRemoteAgentService)), ( __param(7, IContextKeyService))], MainThreadTunnelService); export { MainThreadTunnelService };