UNPKG

@microsoft/dev-tunnels-connections

Version:

Tunnels library for Visual Studio tools

169 lines 6.95 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. Object.defineProperty(exports, "__esModule", { value: true }); exports.TunnelConnectionBase = void 0; const dev_tunnels_ssh_1 = require("@microsoft/dev-tunnels-ssh"); const vscode_jsonrpc_1 = require("vscode-jsonrpc"); const connectionStatus_1 = require("./connectionStatus"); const connectionStatusChangedEventArgs_1 = require("./connectionStatusChangedEventArgs"); const refreshingTunnelAccessTokenEventArgs_1 = require("./refreshingTunnelAccessTokenEventArgs"); const utils_1 = require("./utils"); const sshKeepAliveEventArgs_1 = require("./sshKeepAliveEventArgs"); /** * Tunnel connection base class. */ class TunnelConnectionBase { constructor( /** * Gets tunnel access scope for this tunnel session. */ tunnelAccessScope) { this.tunnelAccessScope = tunnelAccessScope; this.disposeCts = new vscode_jsonrpc_1.CancellationTokenSource(); this.status = connectionStatus_1.ConnectionStatus.None; this.refreshingTunnelAccessTokenEmitter = new utils_1.TrackingEmitter(); this.connectionStatusChangedEmitter = new vscode_jsonrpc_1.Emitter(); this.retryingTunnelConnectionEmitter = new vscode_jsonrpc_1.Emitter(); this.forwardedPortConnectingEmitter = new vscode_jsonrpc_1.Emitter(); this.keepAliveFailedEmitter = new vscode_jsonrpc_1.Emitter(); this.keepAliveSucceededEmitter = new vscode_jsonrpc_1.Emitter(); /** * Event for refreshing the tunnel access token. * The tunnel client will fire this event when it is not able to use the access token it got from the tunnel. */ this.refreshingTunnelAccessToken = this.refreshingTunnelAccessTokenEmitter.event; /** * Connection status changed event. */ this.connectionStatusChanged = this.connectionStatusChangedEmitter.event; /** * Event raised when a tunnel connection attempt failed and is about to be retried. * An event handler can cancel the retry by setting {@link RetryingTunnelConnectionEventArgs.retry} to false. */ this.retryingTunnelConnection = this.retryingTunnelConnectionEmitter.event; /** * An event which fires when a connection is made to the forwarded port. */ this.forwardedPortConnecting = this.forwardedPortConnectingEmitter.event; /** * Event raised when a keep-alive message response is not received. */ this.keepAliveFailed = this.keepAliveFailedEmitter.event; /** * Event raised when a keep-alive message response is received. */ this.keepAliveSucceeded = this.keepAliveSucceededEmitter.event; } /** * Gets a value indicathing that this tunnel connection session is disposed. */ get isDisposed() { return this.disposeCts.token.isCancellationRequested; } get isRefreshingTunnelAccessTokenEventHandled() { return this.refreshingTunnelAccessTokenEmitter.isSubscribed; } /** * Gets dispose cancellation token. */ get disposeToken() { return this.disposeCts.token; } /** * Gets the connection status. */ get connectionStatus() { return this.status; } /** * Sets the connection status. * Throws CancellationError if the session is disposed and the status being set is not ConnectionStatus.Disconnected. */ set connectionStatus(value) { if (this.isDisposed && value !== connectionStatus_1.ConnectionStatus.Disconnected) { this.throwIfDisposed(`ConnectionStatus: ${value}`); } if (value === connectionStatus_1.ConnectionStatus.RefreshingTunnelAccessToken && this.status !== connectionStatus_1.ConnectionStatus.Connecting) { throw new Error('Refreshing tunnel access token is allowed only when connecting.'); } if (value !== this.status) { const previousStatus = this.connectionStatus; this.status = value; this.onConnectionStatusChanged(previousStatus, value); } } /** * Gets the error that caused disconnection. * Undefined if not yet connected or disconnection was caused by disposing of this object. */ get disconnectError() { return this.error; } /** * Sets the error that caused disconnection. */ set disconnectError(e) { this.error = e; } onForwardedPortConnecting(e) { this.forwardedPortConnectingEmitter.fire(e); } /** * Raises the keep-alive failed event. */ onKeepAliveFailed(count) { this.keepAliveFailedEmitter.fire(new sshKeepAliveEventArgs_1.SshKeepAliveEventArgs(count)); } /** * Raises the keep-alive succeeded event. */ onKeepAliveSucceeded(count) { this.keepAliveSucceededEmitter.fire(new sshKeepAliveEventArgs_1.SshKeepAliveEventArgs(count)); } /** * Closes and disposes the tunnel session. */ dispose() { this.disposeCts.cancel(); this.connectionStatus = connectionStatus_1.ConnectionStatus.Disconnected; return Promise.resolve(); } /** * Notifies about a connection retry, giving the relay client a chance to delay or cancel it. */ onRetrying(event) { this.retryingTunnelConnectionEmitter.fire(event); } /** * Gets the fresh tunnel access token or undefined if it cannot. */ async getFreshTunnelAccessToken(cancellation) { const event = new refreshingTunnelAccessTokenEventArgs_1.RefreshingTunnelAccessTokenEventArgs(this.tunnelAccessScope, cancellation); this.refreshingTunnelAccessTokenEmitter.fire(event); return event.tunnelAccessToken ? await event.tunnelAccessToken : undefined; } /** * Event fired when the connection status has changed. */ onConnectionStatusChanged(previousStatus, status) { // Disconnect error is provided only during disconnection, not disposal. const disconnectError = this.connectionStatus === connectionStatus_1.ConnectionStatus.Disconnected && !this.isDisposed ? this.disconnectError : undefined; const event = new connectionStatusChangedEventArgs_1.ConnectionStatusChangedEventArgs(previousStatus, status, disconnectError); this.connectionStatusChangedEmitter.fire(event); } /** * Throws CancellationError if the tunnel connection is disposed. */ throwIfDisposed(message, stack) { if (this.isDisposed) { const error = new dev_tunnels_ssh_1.ObjectDisposedError(`The tunnel connection is disposed. ${message}`); if (stack) { error.stack = stack; } throw error; } } } exports.TunnelConnectionBase = TunnelConnectionBase; //# sourceMappingURL=tunnelConnectionBase.js.map