class Vmess { add?: string; aid?: any; // This could be number or string depending on usage alpn?: string; fp?: string; host?: string; id?: string; net?: string; path?: string; port?: any; // This could be a number or string ps?: string; scy?: string; sni?: string; tls?: string; type?: string; v?: string; constructor(data: { add?: string; aid?: any; alpn?: string; fp?: string; host?: string; id?: string; net?: string; path?: string; port?: any; ps?: string; scy?: string; sni?: string; tls?: string; type?: string; v?: string; }) { this.add = data.add; this.aid = data.aid; this.alpn = data.alpn; this.fp = data.fp; this.host = data.host; this.id = data.id; this.net = data.net; this.path = data.path; this.port = data.port; this.ps = data.ps; this.scy = data.scy; this.sni = data.sni; this.tls = data.tls; this.type = data.type; this.v = data.v; } // 编码 Vmess URL encodeURL(): string { // 如果备注为空,则使用服务器地址 + 端口 if (!this.ps) { this.ps = `${this.add}:${this.port}`; } // 如果版本为空,则默认为 2 if (!this.v) { this.v = '2'; } const param = JSON.stringify(this); return 'vmess://' + this.base64Encode(param); } // 解码 Vmess URL static decodeURL(url: string): Vmess { if (!url.startsWith('vmess://')) { throw new Error(`Invalid vmess URL: ${url}`); } const param = url.slice(8); // Remove "vmess://" const decoded = Vmess.base64Decode(param.trim()); try { const parsed = JSON.parse(decoded); if (parsed.scy === '') { parsed.scy = 'auto'; } if (!parsed.ps) { parsed.ps = parsed.add + ':' + parsed.port; } return new Vmess(parsed); } catch (error) { throw new Error(`Failed to parse VMESS URL: ${error}`); } } // Base64 编码 private base64Encode(str: string): string { return Buffer.from(str, 'utf-8').toString('base64'); } // Base64 解码 private static base64Decode(str: string): string { return Buffer.from(str, 'base64').toString('utf-8'); } } // 开发者测试 function callVmessURL() { const vmess = new Vmess({ add: 'xx.xxx.ru', port: '2095', aid: 0, scy: 'auto', net: 'ws', type: 'none', id: '7a737f41-b792-4260-94ff-3d864da67380', host: 'xx.xxx.ru', path: '/', tls: '' }); const encoded = vmess.encodeURL(); console.log('Encoded VMESS URL:', encoded); const decoded = Vmess.decodeURL(encoded); console.log('Decoded VMESS:', decoded); } callVmessURL();