import type { ParsedNode } from './ss.js'; export function parseVless(uri: string): ParsedNode { const url = new URL(uri); const name = decodeURIComponent(url.hash.slice(1)) || 'VLESS'; const server = url.hostname; const port = parseInt(url.port, 10); const uuid = url.username; const params = url.searchParams; const security = params.get('security') || 'none'; const type = params.get('type') || 'tcp'; const sni = params.get('sni') || ''; const flow = params.get('flow') || ''; let line = `${name} = vless, ${server}, ${port}, username=${uuid}`; if (security === 'reality') { const pbk = params.get('pbk') || ''; const sid = params.get('sid') || ''; line += ', tls=true'; if (sni) line += `, sni=${sni}`; if (pbk) line += `, reality-public-key=${pbk}`; if (sid) line += `, reality-short-id=${sid}`; line += ', skip-cert-verify=false'; } else if (security === 'tls') { line += ', tls=true'; if (sni) line += `, sni=${sni}`; line += ', skip-cert-verify=false'; } if (type === 'ws') { const path = params.get('path') || '/'; const host = params.get('host') || sni || server; line += ', ws=true'; line += `, ws-path=${path}`; line += `, ws-headers=Host:${host}`; } else if (type === 'grpc') { const serviceName = params.get('serviceName') || ''; if (serviceName) line += `, grpc-service-name=${serviceName}`; } if (flow === 'xtls-rprx-vision') { line += ', flow=xtls-rprx-vision'; } return { name, type: 'vless', server, port, surgeLine: line }; }