import { decodeAndTrim, parseBoolOrPresence, parseIpVersion, parsePortOrDefault, parseQueryStringNormalized, parseUrlLike, safeDecodeURIComponent, splitOnce, stripUriScheme, } from "./helpers"; export function URI_SOCKS(line: string): IProxySocks5Config { const afterScheme = stripUriScheme( line, ["socks5", "socks"], "Invalid socks uri", ); if (!afterScheme) { throw new Error("Invalid socks uri"); } const { auth: authRaw, host: server, port, query: addons, fragment: nameRaw, } = parseUrlLike(afterScheme, { errorMessage: "Invalid socks uri" }); const portNum = parsePortOrDefault(port, 443); const auth = safeDecodeURIComponent(authRaw) ?? authRaw; const decodedName = decodeAndTrim(nameRaw); const name = decodedName ?? `SOCKS5 ${server}:${portNum}`; const proxy: IProxySocks5Config = { type: "socks5", name, server, port: portNum, }; if (auth) { const [username, password] = splitOnce(auth, ":"); proxy.username = username; proxy.password = password; } const params = parseQueryStringNormalized(addons); for (const [key, value] of Object.entries(params)) { switch (key) { case "tls": proxy.tls = parseBoolOrPresence(value); break; case "fingerprint": proxy.fingerprint = value; break; case "skip-cert-verify": proxy["skip-cert-verify"] = parseBoolOrPresence(value); break; case "udp": proxy.udp = parseBoolOrPresence(value); break; case "ip-version": proxy["ip-version"] = parseIpVersion(value); break; default: break; } } return proxy; }