import * as plugins from './smartvpn.plugins.js'; import { VpnBridge } from './smartvpn.classes.vpnbridge.js'; import type { IVpnClientOptions, IVpnClientConfig, IVpnStatus, IVpnStatistics, TVpnClientCommands, } from './smartvpn.interfaces.js'; /** * VPN Client — manages a smartvpn daemon in client mode. */ export class VpnClient extends plugins.events.EventEmitter { private bridge: VpnBridge; private options: IVpnClientOptions; constructor(options: IVpnClientOptions) { super(); this.options = options; this.bridge = new VpnBridge({ transport: options.transport, mode: 'client', }); // Forward bridge events this.bridge.on('exit', (code: number | null, signal: string | null) => { this.emit('exit', { code, signal }); }); this.bridge.on('reconnected', () => { this.emit('reconnected'); }); } /** * Start the daemon bridge (spawn or connect). */ public async start(): Promise { return this.bridge.start(); } /** * Connect to the VPN server using the provided config. */ public async connect(config?: IVpnClientConfig): Promise<{ assignedIp: string }> { const cfg = config || this.options.config; if (!cfg) { throw new Error('VpnClient.connect: no config provided'); } return this.bridge.sendCommand('connect', { config: cfg }); } /** * Disconnect from the VPN server. */ public async disconnect(): Promise { await this.bridge.sendCommand('disconnect', {} as Record); } /** * Get current connection status. */ public async getStatus(): Promise { return this.bridge.sendCommand('getStatus', {} as Record); } /** * Get traffic statistics. */ public async getStatistics(): Promise { return this.bridge.sendCommand('getStatistics', {} as Record); } /** * Stop the daemon bridge. */ public stop(): void { this.bridge.stop(); } /** * Whether the bridge is running. */ public get running(): boolean { return this.bridge.running; } }