nodelistparser 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -0
- package/dist/{cjs/index.d.ts → index.d.ts} +24 -3
- package/dist/index.mjs +1 -0
- package/package.json +17 -20
- package/dist/cjs/index.js +0 -1
- package/dist/es/index.d.mts +0 -281
- package/dist/es/index.mjs +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var s=require("foxts/guard"),e=require("foxts/string-join"),r=require("foxts/uint8array-utils");let t=Number,o=s=>s.split(",").map(s=>s.trim());function p(s){let e=s.indexOf("=");return -1===e?["",""]:[s.slice(0,e).trim(),s.slice(e+1).trim()]}let n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),i=new Set(["version","download-bandwidth","port-hopping-interval","udp-port","shadow-tls-version"]),a=new Set,d=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token","underlying-proxy","shadow-tls-password","shadow-tls-sni"]),u=Symbol("unsupported");function l(s){return s.split(",").reduce((s,e)=>{let[r,t]=e.split(":"),o=t.trim();return(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),s[r.trim()]=o,s},{})}function w(s){let e,r,[o,p]=s.split("://");if("ss"!==o)throw Error(`[ss.decodeOne] Unsupported type: ${o}`);let[n,i]=p.split("@");n.includes(":")?[e,...r]=n.split(":",3):[e,...r]=atob(n).split(":",3),r=r.join(":");let[a,d]=i.split(":"),[u,l]=d.split("#"),[w,c]=u.split("/"),h=null;if(c)try{h=new URLSearchParams(c).get("plugin")}catch(e){let s=Error(`[ss.decodeOne] Invalid plugins: ${c}`);throw s.cause=e,s}let y=(h?.split(";")??[]).reduce((s,e)=>{let[r,t]=e.split("=");return s[r]=t,s},{});return{raw:s,type:"ss",name:decodeURIComponent(l),server:a,port:t(w),cipher:e,password:r,udp:!0,obfs:"obfs-local"in y&&"obfs"in y&&("http"===y.obfs||"tls"===y.obfs)?y.obfs:void 0,obfsHost:"obfs-host"in y?y["obfs-host"]:void 0}}function c(s){return atob(s).replaceAll("\r\n","\n").split("\n").filter(Boolean)}exports.clash={__proto__:null,decode:function(s){if(!("type"in s)||"string"!=typeof s.type)throw TypeError("Missing or invalid type field");let e=JSON.stringify(s);switch(s.type){case"http":return{type:"http",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,underlyingProxy:s["dialer-proxy"],raw:e};case"ss":return{type:"ss",name:s.name,server:s.server,port:Number(s.port),cipher:s.cipher,password:s.password,udp:s.udp||!1,obfs:"obfs"===s.plugin?s["plugin-opts"].mode:void 0,underlyingProxy:s["dialer-proxy"],shadowTlsSni:"shadow-tls"===s.plugin?s["plugin-opts"].host:void 0,shadowTlsPassword:"shadow-tls"===s.plugin?s["plugin-opts"].password:void 0,shadowTlsVersion:"shadow-tls"===s.plugin?s["plugin-opts"].version:void 0,raw:e};case"socks5":return{type:"socks5",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],raw:e};case"trojan":return{type:"trojan",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],ws:"ws"===s.network,wsPath:s["ws-opts"]?.path,wsHeaders:s["ws-opts"]?.headers?Object.entries(s["ws-opts"]?.headers).map(([s,e])=>`${s}:${e}`).join(", "):void 0,raw:e};case"vmess":return{type:"vmess",name:s.name,server:s.server,port:Number(s.port),username:s.uuid,vmessAead:0===s.alterId||"0"===s.alterId,sni:s.servername,ws:"ws"===s.network,wsPath:s["ws-path"],wsHeaders:s["ws-headers"]?Object.entries(s["ws-headers"]).map(([s,e])=>`${s}:${e}`).join(", "):void 0,tls:s.tls||!1,udp:s.udp??!0,underlyingProxy:s["dialer-proxy"],raw:e,skipCertVerify:s["skip-cert-verify"]||!1};case"anytls":return{type:"anytls",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!0,reuse:!!s["idle-session-check-interval"]||!!s["idle-session-timeout"]||!!s["min-idle-session"],underlyingProxy:s["dialer-proxy"],raw:e};default:throw TypeError(`Unsupported type: ${s.type} (clash decode)`)}},encode:function(e){let r={name:e.name,server:e.server,port:e.port,tfo:e.tfo,"dialer-proxy":e.underlyingProxy};switch(e.type){case"ss":if(e.shadowTlsPassword&&(e.udp||e.udpPort))throw Error("Clash doesn't support plain UDP for Shadow TLS (clash encode)");return{type:"ss",cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...e.shadowTlsPassword?{plugin:"shadow-tls","plugin-opts":{host:e.shadowTlsSni,password:e.shadowTlsPassword,version:e.shadowTlsVersion}}:{},...r};case"trojan":return{type:"trojan",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?l(e.wsHeaders):void 0}:void 0,...r};case"tuic":case"tuic-v5":return{type:"tuic",sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(s=>s.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,version:"tuic"===e.type?4:"tuic-v5"===e.type?5:s.never(e),...r};case"socks5":return{type:"socks5",username:e.username,password:e.password,udp:e.udp,...r};case"http":return{type:"http",username:e.username,password:e.password,...r};case"vmess":return{alterId:+!e.vmessAead,tls:e.tls,udp:e.udp,uuid:e.username,servername:e.sni,cipher:"auto",network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?l(e.wsHeaders):void 0}:void 0,type:"vmess",...r};case"hysteria2":return{type:"hysteria2",ports:e.port+","+e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify,...r};case"anytls":return{type:"anytls",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp||!0,"idle-session-check-interval":e.reuse?30:void 0,"idle-session-timeout":e.reuse?30:void 0,"min-idle-session":e.reuse?5:void 0,...r};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}},exports.ss={__proto__:null,decodeBase64Multiline:c,decodeMultiline:function(s){return c(s).map(s=>w(s))},decodeOne:w},exports.surge={__proto__:null,decode:function(s){let[e,r]=p(s),[l,w,c,...h]=o(r),y=t(c),v=Object.fromEntries(h.map(s=>{let[e,r]=p(s);return n.has(e)?[e,"true"===r]:i.has(e)?[e,t(r)]:a.has(e)?[e,o(r)]:d.has(e)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[e,r.slice(1,-1)]:[e,r]:[e,u]})),m={raw:s,name:e,server:w,port:y,tfo:v.tfo,blockQuic:v["block-quic"],underlyingProxy:v["underlying-proxy"]},f={sni:v.sni,skipCertVerify:v["skip-cert-verify"]};switch(l){case"snell":return{type:"snell",psk:v.psk,version:v.version,reuse:v.reuse,...m};case"ss":{let s=v["shadow-tls-password"],e=v["shadow-tls-sni"],r=v["shadow-tls-version"];return{type:"ss",cipher:v["encrypt-method"],password:v.password,udp:v["udp-relay"],obfs:v.obfs,obfsHost:v["obfs-host"],obfsUri:v["obfs-uri"],udpPort:v["udp-port"],shadowTlsPassword:s,shadowTlsSni:e,shadowTlsVersion:r,...m}}case"trojan":return{type:"trojan",password:v.password,udp:v["udp-relay"],ws:v.ws,wsPath:v["ws-path"],wsHeaders:v["ws-headers"],...f,...m};case"tuic":return{type:"tuic",uuid:v.uuid,alpn:v.alpn,token:v.token,...f,...m};case"tuic-v5":return{type:"tuic-v5",uuid:v.uuid,alpn:v.alpn,password:v.password,...f,...m};case"socks5":return{type:"socks5",username:h[0],password:h[1],udp:v["udp-relay"],...m};case"http":return{type:"http",username:h[0],password:h[1],...m};case"vmess":return{type:"vmess",username:v.username,tls:v.tls,vmessAead:v["vmess-aead"],ws:v.ws,wsPath:v["ws-path"],wsHeaders:v["ws-headers"],udp:v["udp-relay"],...f,...m};case"hysteria2":return{type:"hysteria2",password:v.password,skipCertVerify:v["skip-cert-verify"],downloadBandwidth:v["download-bandwidth"],portHopping:v["port-hopping"],portHoppingInterval:v["port-hopping-interval"],...m};case"anytls":return{type:"anytls",password:v.password,reuse:v.reuse,udp:v["udp-relay"],...f,...m};default:throw TypeError(`Unsupported type: ${l} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`,r.underlyingProxy&&`underlying-proxy=${r.underlyingProxy}`];switch(r.type){case"snell":return e.stringJoin([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return e.stringJoin([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,r.shadowTlsPassword&&`shadow-tls-password=${r.shadowTlsPassword}`,r.shadowTlsSni&&`shadow-tls-sni=${r.shadowTlsSni}`,r.shadowTlsVersion&&`shadow-tls-version=${r.shadowTlsVersion}`,r.udp&&"udp-relay=true",r.udpPort&&`udp-port=${r.udpPort}`,r.obfs&&`obfs=${r.obfs}`,r.obfsHost&&`obfs-host=${r.obfsHost}`,r.obfsUri&&`obfs-uri=${r.obfsUri}`,...t],", ");case"trojan":return e.stringJoin([`${r.name} = trojan, ${r.server}, ${r.port}, password=${r.password}`,r.sni&&`sni=${r.sni}`,r.skipCertVerify&&"skip-cert-verify=true",...t,r.udp&&"udp-relay=true",r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`],", ");case"tuic":return e.stringJoin([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return e.stringJoin([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return e.stringJoin([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return e.stringJoin([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`,`skip-cert-verify=${r.skipCertVerify}`,`tfo=${r.tfo}`,`udp-relay=${r.udp}`],", ");case"hysteria2":return e.stringJoin([`${r.name} = hysteria2, ${r.server}, ${r.port}`,`password=${r.password}`,`download-bandwidth=${r.downloadBandwidth}`,r.portHopping&&`port-hopping="${r.portHopping}"`,r.portHoppingInterval&&`port-hopping-interval=${r.portHoppingInterval}`,`skip-cert-verify=${r.skipCertVerify}`,...t],", ");case"tuic-v5":return e.stringJoin([`${r.name} = tuic-v5, ${r.server}, ${r.port}`,`password=${r.password}`,`uuid=${r.uuid}`,`alpn=${r.alpn}`,`skip-cert-verify=${r.skipCertVerify}`,`sni=${r.sni}`,...t],", ");case"anytls":return e.stringJoin([`${r.name} = anytls, ${r.server}, ${r.port}, password=${r.password}`,`skip-cert-verify=${r.skipCertVerify}`,r.sni&&`sni=${r.sni}`,`reuse=${r.reuse}`,...t],", ");default:s.never(r,"config.type (surge encode)")}}},exports.trojan={__proto__:null,parse:function(s){let e=new URL(s),r=e.username,t=e.hostname,o=Number.parseInt(e.port,10);return{raw:s,name:decodeURIComponent(e.hash.slice(1)),type:"trojan",server:t,port:o,password:r,udp:!0,sni:e.searchParams.get("sni")??t,skipCertVerify:!0}}},exports.vmess={__proto__:null,parse:function(s){let e=JSON.parse(r.uint8ArrayToString(r.base64ToUint8Array(s.slice(8)))),t=e.ps,o=e.path;return{raw:s,name:t,server:e.add,port:Number.parseInt(e.port,10),type:"vmess",username:e.id,tls:e.tls,vmessAead:"0"===e.aid,sni:e.sni,ws:"ws"===e.net,wsPath:"/"===o[0]?o:`/${o}`,wsHeaders:e.sni||e.host?`Host:${e.sni||e.host}`:e.add,skipCertVerify:!0,udp:!0}}};
|
|
@@ -60,6 +60,13 @@ interface SnellConfig extends SharedConfigBase {
|
|
|
60
60
|
version: number;
|
|
61
61
|
reuse: boolean;
|
|
62
62
|
}
|
|
63
|
+
interface AnyTLSConfig extends SharedConfigBase, TlsSharedConfig {
|
|
64
|
+
type: 'anytls';
|
|
65
|
+
password: string;
|
|
66
|
+
/** udp-relay */
|
|
67
|
+
udp: boolean;
|
|
68
|
+
reuse: boolean;
|
|
69
|
+
}
|
|
63
70
|
interface TrojanBasicConfig extends SharedConfigBase, TlsSharedConfig {
|
|
64
71
|
type: 'trojan';
|
|
65
72
|
password: string;
|
|
@@ -105,7 +112,7 @@ interface Hysteria2Config extends SharedConfigBase, Omit<TlsSharedConfig, 'sni'>
|
|
|
105
112
|
/** port hopping interval */
|
|
106
113
|
portHoppingInterval?: number;
|
|
107
114
|
}
|
|
108
|
-
type SupportedConfig = HttpProxyConfig | SnellConfig | TrojanConfig | ShadowSocksConfig | TuicConfig | TuicV5Config | Socks5Config | VmessConfig | Hysteria2Config;
|
|
115
|
+
type SupportedConfig = HttpProxyConfig | SnellConfig | TrojanConfig | ShadowSocksConfig | TuicConfig | TuicV5Config | Socks5Config | VmessConfig | Hysteria2Config | AnyTLSConfig;
|
|
109
116
|
|
|
110
117
|
declare function decode$1(raw: string): SupportedConfig;
|
|
111
118
|
declare function encode$1(config: SupportedConfig): string;
|
|
@@ -211,7 +218,7 @@ declare function encode(config: SupportedConfig): {
|
|
|
211
218
|
port: number;
|
|
212
219
|
tfo: boolean | undefined;
|
|
213
220
|
'dialer-proxy': string | undefined;
|
|
214
|
-
alterId: number
|
|
221
|
+
alterId: number;
|
|
215
222
|
tls: boolean;
|
|
216
223
|
udp: boolean;
|
|
217
224
|
uuid: string;
|
|
@@ -234,6 +241,20 @@ declare function encode(config: SupportedConfig): {
|
|
|
234
241
|
password: string;
|
|
235
242
|
down: string;
|
|
236
243
|
'skip-cert-verify': boolean;
|
|
244
|
+
} | {
|
|
245
|
+
name: string;
|
|
246
|
+
server: string;
|
|
247
|
+
port: number;
|
|
248
|
+
tfo: boolean | undefined;
|
|
249
|
+
'dialer-proxy': string | undefined;
|
|
250
|
+
type: string;
|
|
251
|
+
password: string;
|
|
252
|
+
sni: string | undefined;
|
|
253
|
+
'skip-cert-verify': boolean;
|
|
254
|
+
udp: true;
|
|
255
|
+
'idle-session-check-interval': number | undefined;
|
|
256
|
+
'idle-session-timeout': number | undefined;
|
|
257
|
+
'min-idle-session': number | undefined;
|
|
237
258
|
};
|
|
238
259
|
|
|
239
260
|
declare const index$3_decode: typeof decode;
|
|
@@ -278,4 +299,4 @@ declare namespace index {
|
|
|
278
299
|
}
|
|
279
300
|
|
|
280
301
|
export { index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
|
|
281
|
-
export type { HttpProxyConfig, Hysteria2Config, ShadowSocksConfig, SharedConfigBase, SnellConfig, Socks5Config, SupportedConfig, TlsSharedConfig, TrojanBasicConfig, TrojanConfig, TuicConfig, TuicV5Config, VmessConfig };
|
|
302
|
+
export type { AnyTLSConfig, HttpProxyConfig, Hysteria2Config, ShadowSocksConfig, SharedConfigBase, SnellConfig, Socks5Config, SupportedConfig, TlsSharedConfig, TrojanBasicConfig, TrojanConfig, TuicConfig, TuicV5Config, VmessConfig };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{never as s}from"foxts/guard";import{stringJoin as e}from"foxts/string-join";import{uint8ArrayToString as r,base64ToUint8Array as t}from"foxts/uint8array-utils";let o=Number,p=s=>s.split(",").map(s=>s.trim());function a(s){let e=s.indexOf("=");return -1===e?["",""]:[s.slice(0,e).trim(),s.slice(e+1).trim()]}let n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),i=new Set(["version","download-bandwidth","port-hopping-interval","udp-port","shadow-tls-version"]),d=new Set,u=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token","underlying-proxy","shadow-tls-password","shadow-tls-sni"]),l=Symbol("unsupported");var w={__proto__:null,decode:function(s){let[e,r]=a(s),[t,w,c,...h]=p(r),y=o(c),m=Object.fromEntries(h.map(s=>{let[e,r]=a(s);return n.has(e)?[e,"true"===r]:i.has(e)?[e,o(r)]:d.has(e)?[e,p(r)]:u.has(e)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[e,r.slice(1,-1)]:[e,r]:[e,l]})),f={raw:s,name:e,server:w,port:y,tfo:m.tfo,blockQuic:m["block-quic"],underlyingProxy:m["underlying-proxy"]},v={sni:m.sni,skipCertVerify:m["skip-cert-verify"]};switch(t){case"snell":return{type:"snell",psk:m.psk,version:m.version,reuse:m.reuse,...f};case"ss":{let s=m["shadow-tls-password"],e=m["shadow-tls-sni"],r=m["shadow-tls-version"];return{type:"ss",cipher:m["encrypt-method"],password:m.password,udp:m["udp-relay"],obfs:m.obfs,obfsHost:m["obfs-host"],obfsUri:m["obfs-uri"],udpPort:m["udp-port"],shadowTlsPassword:s,shadowTlsSni:e,shadowTlsVersion:r,...f}}case"trojan":return{type:"trojan",password:m.password,udp:m["udp-relay"],ws:m.ws,wsPath:m["ws-path"],wsHeaders:m["ws-headers"],...v,...f};case"tuic":return{type:"tuic",uuid:m.uuid,alpn:m.alpn,token:m.token,...v,...f};case"tuic-v5":return{type:"tuic-v5",uuid:m.uuid,alpn:m.alpn,password:m.password,...v,...f};case"socks5":return{type:"socks5",username:h[0],password:h[1],udp:m["udp-relay"],...f};case"http":return{type:"http",username:h[0],password:h[1],...f};case"vmess":return{type:"vmess",username:m.username,tls:m.tls,vmessAead:m["vmess-aead"],ws:m.ws,wsPath:m["ws-path"],wsHeaders:m["ws-headers"],udp:m["udp-relay"],...v,...f};case"hysteria2":return{type:"hysteria2",password:m.password,skipCertVerify:m["skip-cert-verify"],downloadBandwidth:m["download-bandwidth"],portHopping:m["port-hopping"],portHoppingInterval:m["port-hopping-interval"],...f};case"anytls":return{type:"anytls",password:m.password,reuse:m.reuse,udp:m["udp-relay"],...v,...f};default:throw TypeError(`Unsupported type: ${t} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`,r.underlyingProxy&&`underlying-proxy=${r.underlyingProxy}`];switch(r.type){case"snell":return e([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return e([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,r.shadowTlsPassword&&`shadow-tls-password=${r.shadowTlsPassword}`,r.shadowTlsSni&&`shadow-tls-sni=${r.shadowTlsSni}`,r.shadowTlsVersion&&`shadow-tls-version=${r.shadowTlsVersion}`,r.udp&&"udp-relay=true",r.udpPort&&`udp-port=${r.udpPort}`,r.obfs&&`obfs=${r.obfs}`,r.obfsHost&&`obfs-host=${r.obfsHost}`,r.obfsUri&&`obfs-uri=${r.obfsUri}`,...t],", ");case"trojan":return e([`${r.name} = trojan, ${r.server}, ${r.port}, password=${r.password}`,r.sni&&`sni=${r.sni}`,r.skipCertVerify&&"skip-cert-verify=true",...t,r.udp&&"udp-relay=true",r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`],", ");case"tuic":return e([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return e([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return e([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return e([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`,`skip-cert-verify=${r.skipCertVerify}`,`tfo=${r.tfo}`,`udp-relay=${r.udp}`],", ");case"hysteria2":return e([`${r.name} = hysteria2, ${r.server}, ${r.port}`,`password=${r.password}`,`download-bandwidth=${r.downloadBandwidth}`,r.portHopping&&`port-hopping="${r.portHopping}"`,r.portHoppingInterval&&`port-hopping-interval=${r.portHoppingInterval}`,`skip-cert-verify=${r.skipCertVerify}`,...t],", ");case"tuic-v5":return e([`${r.name} = tuic-v5, ${r.server}, ${r.port}`,`password=${r.password}`,`uuid=${r.uuid}`,`alpn=${r.alpn}`,`skip-cert-verify=${r.skipCertVerify}`,`sni=${r.sni}`,...t],", ");case"anytls":return e([`${r.name} = anytls, ${r.server}, ${r.port}, password=${r.password}`,`skip-cert-verify=${r.skipCertVerify}`,r.sni&&`sni=${r.sni}`,`reuse=${r.reuse}`,...t],", ");default:s(r,"config.type (surge encode)")}}};function c(s){return s.split(",").reduce((s,e)=>{let[r,t]=e.split(":"),o=t.trim();return(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),s[r.trim()]=o,s},{})}var h={__proto__:null,decode:function(s){if(!("type"in s)||"string"!=typeof s.type)throw TypeError("Missing or invalid type field");let e=JSON.stringify(s);switch(s.type){case"http":return{type:"http",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,underlyingProxy:s["dialer-proxy"],raw:e};case"ss":return{type:"ss",name:s.name,server:s.server,port:Number(s.port),cipher:s.cipher,password:s.password,udp:s.udp||!1,obfs:"obfs"===s.plugin?s["plugin-opts"].mode:void 0,underlyingProxy:s["dialer-proxy"],shadowTlsSni:"shadow-tls"===s.plugin?s["plugin-opts"].host:void 0,shadowTlsPassword:"shadow-tls"===s.plugin?s["plugin-opts"].password:void 0,shadowTlsVersion:"shadow-tls"===s.plugin?s["plugin-opts"].version:void 0,raw:e};case"socks5":return{type:"socks5",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],raw:e};case"trojan":return{type:"trojan",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],ws:"ws"===s.network,wsPath:s["ws-opts"]?.path,wsHeaders:s["ws-opts"]?.headers?Object.entries(s["ws-opts"]?.headers).map(([s,e])=>`${s}:${e}`).join(", "):void 0,raw:e};case"vmess":return{type:"vmess",name:s.name,server:s.server,port:Number(s.port),username:s.uuid,vmessAead:0===s.alterId||"0"===s.alterId,sni:s.servername,ws:"ws"===s.network,wsPath:s["ws-path"],wsHeaders:s["ws-headers"]?Object.entries(s["ws-headers"]).map(([s,e])=>`${s}:${e}`).join(", "):void 0,tls:s.tls||!1,udp:s.udp??!0,underlyingProxy:s["dialer-proxy"],raw:e,skipCertVerify:s["skip-cert-verify"]||!1};case"anytls":return{type:"anytls",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!0,reuse:!!s["idle-session-check-interval"]||!!s["idle-session-timeout"]||!!s["min-idle-session"],underlyingProxy:s["dialer-proxy"],raw:e};default:throw TypeError(`Unsupported type: ${s.type} (clash decode)`)}},encode:function(e){let r={name:e.name,server:e.server,port:e.port,tfo:e.tfo,"dialer-proxy":e.underlyingProxy};switch(e.type){case"ss":if(e.shadowTlsPassword&&(e.udp||e.udpPort))throw Error("Clash doesn't support plain UDP for Shadow TLS (clash encode)");return{type:"ss",cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...e.shadowTlsPassword?{plugin:"shadow-tls","plugin-opts":{host:e.shadowTlsSni,password:e.shadowTlsPassword,version:e.shadowTlsVersion}}:{},...r};case"trojan":return{type:"trojan",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?c(e.wsHeaders):void 0}:void 0,...r};case"tuic":case"tuic-v5":return{type:"tuic",sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(s=>s.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,version:"tuic"===e.type?4:"tuic-v5"===e.type?5:s(e),...r};case"socks5":return{type:"socks5",username:e.username,password:e.password,udp:e.udp,...r};case"http":return{type:"http",username:e.username,password:e.password,...r};case"vmess":return{alterId:+!e.vmessAead,tls:e.tls,udp:e.udp,uuid:e.username,servername:e.sni,cipher:"auto",network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?c(e.wsHeaders):void 0}:void 0,type:"vmess",...r};case"hysteria2":return{type:"hysteria2",ports:e.port+","+e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify,...r};case"anytls":return{type:"anytls",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp||!0,"idle-session-check-interval":e.reuse?30:void 0,"idle-session-timeout":e.reuse?30:void 0,"min-idle-session":e.reuse?5:void 0,...r};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}};function y(s){let e,r,[t,p]=s.split("://");if("ss"!==t)throw Error(`[ss.decodeOne] Unsupported type: ${t}`);let[a,n]=p.split("@");a.includes(":")?[e,...r]=a.split(":",3):[e,...r]=atob(a).split(":",3),r=r.join(":");let[i,d]=n.split(":"),[u,l]=d.split("#"),[w,c]=u.split("/"),h=null;if(c)try{h=new URLSearchParams(c).get("plugin")}catch(e){let s=Error(`[ss.decodeOne] Invalid plugins: ${c}`);throw s.cause=e,s}let y=(h?.split(";")??[]).reduce((s,e)=>{let[r,t]=e.split("=");return s[r]=t,s},{});return{raw:s,type:"ss",name:decodeURIComponent(l),server:i,port:o(w),cipher:e,password:r,udp:!0,obfs:"obfs-local"in y&&"obfs"in y&&("http"===y.obfs||"tls"===y.obfs)?y.obfs:void 0,obfsHost:"obfs-host"in y?y["obfs-host"]:void 0}}function m(s){return atob(s).replaceAll("\r\n","\n").split("\n").filter(Boolean)}var f={__proto__:null,decodeBase64Multiline:m,decodeMultiline:function(s){return m(s).map(s=>y(s))},decodeOne:y},v={__proto__:null,parse:function(s){let e=new URL(s),r=e.username,t=e.hostname,o=Number.parseInt(e.port,10);return{raw:s,name:decodeURIComponent(e.hash.slice(1)),type:"trojan",server:t,port:o,password:r,udp:!0,sni:e.searchParams.get("sni")??t,skipCertVerify:!0}}},$={__proto__:null,parse:function(s){let e=JSON.parse(r(t(s.slice(8)))),o=e.ps,p=e.path;return{raw:s,name:o,server:e.add,port:Number.parseInt(e.port,10),type:"vmess",username:e.id,tls:e.tls,vmessAead:"0"===e.aid,sni:e.sni,ws:"ws"===e.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:e.sni||e.host?`Host:${e.sni||e.host}`:e.add,skipCertVerify:!0,udp:!0}}};export{h as clash,f as ss,w as surge,v as trojan,$ as vmess};
|
package/package.json
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodelistparser",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Surge / Mihomo (Clash.Meta) nodelist / proxy provider parser and generator.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/SukkaW/nodelistparser"
|
|
8
8
|
},
|
|
9
|
-
"main": "./dist/
|
|
10
|
-
"module": "./dist/
|
|
11
|
-
"types": "./dist/
|
|
9
|
+
"main": "./dist/index.cjs",
|
|
10
|
+
"module": "./dist/index.mjs",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"default": "./dist/cjs/index.js"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs",
|
|
20
|
+
"default": "./dist/index.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
26
23
|
},
|
|
27
24
|
"keywords": [
|
|
28
25
|
"clash",
|
|
@@ -34,19 +31,19 @@
|
|
|
34
31
|
"author": "Sukka <https://skk.moe>",
|
|
35
32
|
"license": "MIT",
|
|
36
33
|
"dependencies": {
|
|
37
|
-
"foxts": "^5.0.
|
|
34
|
+
"foxts": "^5.0.3"
|
|
38
35
|
},
|
|
39
36
|
"devDependencies": {
|
|
40
|
-
"@eslint-sukka/node": "^8.0.
|
|
37
|
+
"@eslint-sukka/node": "^8.0.5",
|
|
41
38
|
"@swc-node/register": "^1.11.1",
|
|
42
|
-
"@swc/core": "^1.15.
|
|
39
|
+
"@swc/core": "^1.15.3",
|
|
43
40
|
"@types/mocha": "^10.0.10",
|
|
44
|
-
"@types/node": "^24.10.
|
|
45
|
-
"bumpp": "^10.3.
|
|
41
|
+
"@types/node": "^24.10.3",
|
|
42
|
+
"bumpp": "^10.3.2",
|
|
46
43
|
"bunchee": "^6.6.2",
|
|
47
44
|
"eslint": "^9.39.1",
|
|
48
|
-
"eslint-config-sukka": "^8.0.
|
|
49
|
-
"eslint-formatter-sukka": "^8.0.
|
|
45
|
+
"eslint-config-sukka": "^8.0.5",
|
|
46
|
+
"eslint-formatter-sukka": "^8.0.5",
|
|
50
47
|
"expect": "^30.2.0",
|
|
51
48
|
"mocha": "^11.7.5",
|
|
52
49
|
"typescript": "^5.9.3"
|
package/dist/cjs/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var s=require("foxts/guard"),e=require("foxts/string-join"),r=require("foxts/uint8array-utils");let t=Number,o=s=>s.split(",").map(s=>s.trim());function p(s){let e=s.indexOf("=");return -1===e?["",""]:[s.slice(0,e).trim(),s.slice(e+1).trim()]}let n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),a=new Set(["version","download-bandwidth","port-hopping-interval","udp-port","shadow-tls-version"]),i=new Set([]),d=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token","underlying-proxy","shadow-tls-password","shadow-tls-sni"]),u=Symbol("unsupported");function l(s){return s.split(",").reduce((s,e)=>{let[r,t]=e.split(":"),o=t.trim();return(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),s[r.trim()]=o,s},{})}function w(s){let e,r,[o,p]=s.split("://");if("ss"!==o)throw Error(`[ss.decodeOne] Unsupported type: ${o}`);let[n,a]=p.split("@");n.includes(":")?[e,...r]=n.split(":",3):[e,...r]=atob(n).split(":",3),r=r.join(":");let[i,d]=a.split(":"),[u,l]=d.split("#"),[w,c]=u.split("/"),h=null;if(c)try{h=new URLSearchParams(c).get("plugin")}catch(e){let s=Error(`[ss.decodeOne] Invalid plugins: ${c}`);throw s.cause=e,s}let y=(h?.split(";")??[]).reduce((s,e)=>{let[r,t]=e.split("=");return s[r]=t,s},{});return{raw:s,type:"ss",name:decodeURIComponent(l),server:i,port:t(w),cipher:e,password:r,udp:!0,obfs:"obfs-local"in y&&"obfs"in y&&("http"===y.obfs||"tls"===y.obfs)?y.obfs:void 0,obfsHost:"obfs-host"in y?y["obfs-host"]:void 0}}function c(s){return atob(s).replaceAll("\r\n","\n").split("\n").filter(Boolean)}exports.clash={__proto__:null,decode:function(s){if(!("type"in s)||"string"!=typeof s.type)throw TypeError("Missing or invalid type field");let e=JSON.stringify(s);switch(s.type){case"http":return{type:"http",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,underlyingProxy:s["dialer-proxy"],raw:e};case"ss":return{type:"ss",name:s.name,server:s.server,port:Number(s.port),cipher:s.cipher,password:s.password,udp:s.udp||!1,obfs:"obfs"===s.plugin?s["plugin-opts"].mode:void 0,underlyingProxy:s["dialer-proxy"],shadowTlsSni:"shadow-tls"===s.plugin?s["plugin-opts"].host:void 0,shadowTlsPassword:"shadow-tls"===s.plugin?s["plugin-opts"].password:void 0,shadowTlsVersion:"shadow-tls"===s.plugin?s["plugin-opts"].version:void 0,raw:e};case"socks5":return{type:"socks5",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],raw:e};case"trojan":return{type:"trojan",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],ws:"ws"===s.network,wsPath:s["ws-opts"]?.path,wsHeaders:s["ws-opts"]?.headers?Object.entries(s["ws-opts"]?.headers).map(([s,e])=>`${s}:${e}`).join(", "):void 0,raw:e};case"vmess":return{type:"vmess",name:s.name,server:s.server,port:Number(s.port),username:s.uuid,vmessAead:1===s.alterId||"1"===s.alterId,sni:s.servername,ws:"ws"===s.network,wsPath:s["ws-path"],wsHeaders:s["ws-headers"]?Object.entries(s["ws-headers"]).map(([s,e])=>`${s}:${e}`).join(", "):void 0,tls:s.tls||!1,udp:s.udp??!0,underlyingProxy:s["dialer-proxy"],raw:e,skipCertVerify:s["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${s.type} (clash decode)`)}},encode:function(e){let r={name:e.name,server:e.server,port:e.port,tfo:e.tfo,"dialer-proxy":e.underlyingProxy};switch(e.type){case"ss":if(e.shadowTlsPassword&&(e.udp||e.udpPort))throw Error("Clash doesn't support plain UDP for Shadow TLS (clash encode)");return{type:"ss",cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...e.shadowTlsPassword?{plugin:"shadow-tls","plugin-opts":{host:e.shadowTlsSni,password:e.shadowTlsPassword,version:e.shadowTlsVersion}}:{},...r};case"trojan":return{type:"trojan",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?l(e.wsHeaders):void 0}:void 0,...r};case"tuic":case"tuic-v5":return{type:"tuic",sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(s=>s.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,version:"tuic"===e.type?4:"tuic-v5"===e.type?5:s.never(e),...r};case"socks5":return{type:"socks5",username:e.username,password:e.password,udp:e.udp,...r};case"http":return{type:"http",username:e.username,password:e.password,...r};case"vmess":return{alterId:e.vmessAead?0:void 0,tls:e.tls,udp:e.udp,uuid:e.username,servername:e.sni,cipher:"auto",network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?l(e.wsHeaders):void 0}:void 0,type:"vmess",...r};case"hysteria2":return{type:"hysteria2",ports:e.port+","+e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify,...r};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}},exports.ss={__proto__:null,decodeBase64Multiline:c,decodeMultiline:function(s){return c(s).map(s=>w(s))},decodeOne:w},exports.surge={__proto__:null,decode:function(s){let[e,r]=p(s),[l,w,c,...h]=o(r),y=t(c),f=Object.fromEntries(h.map(s=>{let[e,r]=p(s);return n.has(e)?[e,"true"===r]:a.has(e)?[e,t(r)]:i.has(e)?[e,o(r)]:d.has(e)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[e,r.slice(1,-1)]:[e,r]:[e,u]})),m={raw:s,name:e,server:w,port:y,tfo:f.tfo,blockQuic:f["block-quic"],underlyingProxy:f["underlying-proxy"]},v={sni:f.sni,skipCertVerify:f["skip-cert-verify"]};switch(l){case"snell":return{type:"snell",psk:f.psk,version:f.version,reuse:f.reuse,...m};case"ss":{let s=f["shadow-tls-password"],e=f["shadow-tls-sni"],r=f["shadow-tls-version"];return{type:"ss",cipher:f["encrypt-method"],password:f.password,udp:f["udp-relay"],obfs:f.obfs,obfsHost:f["obfs-host"],obfsUri:f["obfs-uri"],udpPort:f["udp-port"],shadowTlsPassword:s,shadowTlsSni:e,shadowTlsVersion:r,...m}}case"trojan":return{type:"trojan",password:f.password,udp:f["udp-relay"],ws:f.ws,wsPath:f["ws-path"],wsHeaders:f["ws-headers"],...v,...m};case"tuic":return{type:"tuic",uuid:f.uuid,alpn:f.alpn,token:f.token,...v,...m};case"tuic-v5":return{type:"tuic-v5",uuid:f.uuid,alpn:f.alpn,password:f.password,...v,...m};case"socks5":return{type:"socks5",username:h[0],password:h[1],udp:f["udp-relay"],...m};case"http":return{type:"http",username:h[0],password:h[1],...m};case"vmess":return{type:"vmess",username:f.username,tls:f.tls,vmessAead:f["vmess-aead"],ws:f.ws,wsPath:f["ws-path"],wsHeaders:f["ws-headers"],udp:f["udp-relay"],...v,...m};case"hysteria2":return{type:"hysteria2",password:f.password,skipCertVerify:f["skip-cert-verify"],downloadBandwidth:f["download-bandwidth"],portHopping:f["port-hopping"],portHoppingInterval:f["port-hopping-interval"],...m};default:throw TypeError(`Unsupported type: ${l} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`,r.underlyingProxy&&`underlying-proxy=${r.underlyingProxy}`];switch(r.type){case"snell":return e.stringJoin([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return e.stringJoin([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,r.shadowTlsPassword&&`shadow-tls-password=${r.shadowTlsPassword}`,r.shadowTlsSni&&`shadow-tls-sni=${r.shadowTlsSni}`,r.shadowTlsVersion&&`shadow-tls-version=${r.shadowTlsVersion}`,r.udp&&"udp-relay=true",r.udpPort&&`udp-port=${r.udpPort}`,r.obfs&&`obfs=${r.obfs}`,r.obfsHost&&`obfs-host=${r.obfsHost}`,r.obfsUri&&`obfs-uri=${r.obfsUri}`,...t],", ");case"trojan":return e.stringJoin([`${r.name} = trojan, ${r.server}, ${r.port}, password=${r.password}`,r.sni&&`sni=${r.sni}`,r.skipCertVerify&&"skip-cert-verify=true",...t,r.udp&&"udp-relay=true",r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`],", ");case"tuic":return e.stringJoin([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return e.stringJoin([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return e.stringJoin([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return e.stringJoin([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`,`skip-cert-verify=${r.skipCertVerify}`,`tfo=${r.tfo}`,`udp-relay=${r.udp}`],", ");case"hysteria2":return e.stringJoin([`${r.name} = hysteria2, ${r.server}, ${r.port}`,`password=${r.password}`,`download-bandwidth=${r.downloadBandwidth}`,r.portHopping&&`port-hopping="${r.portHopping}"`,r.portHoppingInterval&&`port-hopping-interval=${r.portHoppingInterval}`,`skip-cert-verify=${r.skipCertVerify}`,...t],", ");case"tuic-v5":return e.stringJoin([`${r.name} = tuic-v5, ${r.server}, ${r.port}`,`password=${r.password}`,`uuid=${r.uuid}`,`alpn=${r.alpn}`,`skip-cert-verify=${r.skipCertVerify}`,`sni=${r.sni}`,...t],", ");default:s.never(r,"type (surge encode)")}}},exports.trojan={__proto__:null,parse:function(s){let e=new URL(s),r=e.username,t=e.hostname,o=Number.parseInt(e.port,10);return{raw:s,name:decodeURIComponent(e.hash.slice(1)),type:"trojan",server:t,port:o,password:r,udp:!0,sni:e.searchParams.get("sni")??t,skipCertVerify:!0}}},exports.vmess={__proto__:null,parse:function(s){let e=JSON.parse(r.uint8ArrayToString(r.base64ToUint8Array(s.slice(8)))),t=e.ps,o=e.path;return{raw:s,name:t,server:e.add,port:Number.parseInt(e.port,10),type:"vmess",username:e.id,tls:e.tls,vmessAead:"0"===e.aid,sni:e.sni,ws:"ws"===e.net,wsPath:"/"===o[0]?o:`/${o}`,wsHeaders:e.sni||e.host?`Host:${e.sni||e.host}`:e.add,skipCertVerify:!0,udp:!0}}};
|
package/dist/es/index.d.mts
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
interface SharedConfigBase {
|
|
2
|
-
raw?: string | undefined | null;
|
|
3
|
-
name: string;
|
|
4
|
-
server: string;
|
|
5
|
-
port: number;
|
|
6
|
-
/** tfo */
|
|
7
|
-
tfo?: boolean;
|
|
8
|
-
/** block-quic */
|
|
9
|
-
blockQuic?: string;
|
|
10
|
-
/** underlying-proxy */
|
|
11
|
-
underlyingProxy?: string;
|
|
12
|
-
}
|
|
13
|
-
interface TlsSharedConfig {
|
|
14
|
-
/** sni */
|
|
15
|
-
sni: string | undefined;
|
|
16
|
-
/** skip-cert-verify */
|
|
17
|
-
skipCertVerify: boolean;
|
|
18
|
-
}
|
|
19
|
-
interface HttpProxyConfig extends SharedConfigBase {
|
|
20
|
-
type: 'http';
|
|
21
|
-
username: string;
|
|
22
|
-
password: string;
|
|
23
|
-
}
|
|
24
|
-
interface ShadowSocksConfig extends SharedConfigBase {
|
|
25
|
-
type: 'ss';
|
|
26
|
-
/** encrypt-method */
|
|
27
|
-
cipher: string;
|
|
28
|
-
password: string;
|
|
29
|
-
/** udp-relay */
|
|
30
|
-
udp: boolean;
|
|
31
|
-
obfs?: undefined | 'http' | 'tls';
|
|
32
|
-
/** obfs-host */
|
|
33
|
-
obfsHost?: string;
|
|
34
|
-
/** obfs-uri */
|
|
35
|
-
obfsUri?: string;
|
|
36
|
-
/** udp-port */
|
|
37
|
-
udpPort?: number;
|
|
38
|
-
/** Shadow TLS Version */
|
|
39
|
-
shadowTlsVersion?: 1 | 2 | 3;
|
|
40
|
-
/** Shadow TLS Password */
|
|
41
|
-
shadowTlsPassword?: string;
|
|
42
|
-
/** Shadow TLS SNI */
|
|
43
|
-
shadowTlsSni?: string | undefined;
|
|
44
|
-
}
|
|
45
|
-
interface TrojanConfig extends SharedConfigBase, TlsSharedConfig {
|
|
46
|
-
type: 'trojan';
|
|
47
|
-
password: string;
|
|
48
|
-
/** udp-relay */
|
|
49
|
-
udp: boolean;
|
|
50
|
-
/** ws */
|
|
51
|
-
ws: boolean | undefined;
|
|
52
|
-
/** ws-path */
|
|
53
|
-
wsPath: string | undefined;
|
|
54
|
-
/** ws-headers */
|
|
55
|
-
wsHeaders: string | undefined;
|
|
56
|
-
}
|
|
57
|
-
interface SnellConfig extends SharedConfigBase {
|
|
58
|
-
type: 'snell';
|
|
59
|
-
psk: string;
|
|
60
|
-
version: number;
|
|
61
|
-
reuse: boolean;
|
|
62
|
-
}
|
|
63
|
-
interface TrojanBasicConfig extends SharedConfigBase, TlsSharedConfig {
|
|
64
|
-
type: 'trojan';
|
|
65
|
-
password: string;
|
|
66
|
-
/** udp-relay */
|
|
67
|
-
udp: boolean;
|
|
68
|
-
}
|
|
69
|
-
interface TuicConfig extends SharedConfigBase, TlsSharedConfig {
|
|
70
|
-
type: 'tuic';
|
|
71
|
-
uuid: string;
|
|
72
|
-
alpn: string;
|
|
73
|
-
token: string;
|
|
74
|
-
}
|
|
75
|
-
interface TuicV5Config extends SharedConfigBase, TlsSharedConfig {
|
|
76
|
-
type: 'tuic-v5';
|
|
77
|
-
uuid: string;
|
|
78
|
-
alpn: string;
|
|
79
|
-
password: string;
|
|
80
|
-
}
|
|
81
|
-
interface Socks5Config extends SharedConfigBase {
|
|
82
|
-
type: 'socks5';
|
|
83
|
-
udp: boolean;
|
|
84
|
-
username: string;
|
|
85
|
-
password: string;
|
|
86
|
-
}
|
|
87
|
-
interface VmessConfig extends SharedConfigBase, TlsSharedConfig {
|
|
88
|
-
type: 'vmess';
|
|
89
|
-
/** uuid */
|
|
90
|
-
username: string;
|
|
91
|
-
tls: boolean;
|
|
92
|
-
vmessAead: boolean | undefined;
|
|
93
|
-
ws: boolean | undefined;
|
|
94
|
-
wsPath: string | undefined;
|
|
95
|
-
wsHeaders: string | undefined;
|
|
96
|
-
udp: boolean;
|
|
97
|
-
}
|
|
98
|
-
interface Hysteria2Config extends SharedConfigBase, Omit<TlsSharedConfig, 'sni'> {
|
|
99
|
-
type: 'hysteria2';
|
|
100
|
-
password: string;
|
|
101
|
-
/** download-bandwidth in mbps */
|
|
102
|
-
downloadBandwidth: number;
|
|
103
|
-
/** port hopping */
|
|
104
|
-
portHopping?: string;
|
|
105
|
-
/** port hopping interval */
|
|
106
|
-
portHoppingInterval?: number;
|
|
107
|
-
}
|
|
108
|
-
type SupportedConfig = HttpProxyConfig | SnellConfig | TrojanConfig | ShadowSocksConfig | TuicConfig | TuicV5Config | Socks5Config | VmessConfig | Hysteria2Config;
|
|
109
|
-
|
|
110
|
-
declare function decode$1(raw: string): SupportedConfig;
|
|
111
|
-
declare function encode$1(config: SupportedConfig): string;
|
|
112
|
-
|
|
113
|
-
declare namespace index$4 {
|
|
114
|
-
export {
|
|
115
|
-
decode$1 as decode,
|
|
116
|
-
encode$1 as encode,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
declare function decode(config: Record<string, any>): SupportedConfig;
|
|
121
|
-
declare function encode(config: SupportedConfig): {
|
|
122
|
-
name: string;
|
|
123
|
-
server: string;
|
|
124
|
-
port: number;
|
|
125
|
-
tfo: boolean | undefined;
|
|
126
|
-
'dialer-proxy': string | undefined;
|
|
127
|
-
plugin?: string | undefined;
|
|
128
|
-
'plugin-opts'?: {
|
|
129
|
-
mode: "http" | "tls";
|
|
130
|
-
host: string | undefined;
|
|
131
|
-
uri: string | undefined;
|
|
132
|
-
password?: undefined;
|
|
133
|
-
version?: undefined;
|
|
134
|
-
} | {
|
|
135
|
-
host: string | undefined;
|
|
136
|
-
password: string;
|
|
137
|
-
version: 1 | 2 | 3 | undefined;
|
|
138
|
-
mode?: undefined;
|
|
139
|
-
uri?: undefined;
|
|
140
|
-
} | undefined;
|
|
141
|
-
type: string;
|
|
142
|
-
cipher: string;
|
|
143
|
-
password: string;
|
|
144
|
-
udp: boolean;
|
|
145
|
-
} | {
|
|
146
|
-
name: string;
|
|
147
|
-
server: string;
|
|
148
|
-
port: number;
|
|
149
|
-
tfo: boolean | undefined;
|
|
150
|
-
'dialer-proxy': string | undefined;
|
|
151
|
-
type: string;
|
|
152
|
-
password: string;
|
|
153
|
-
sni: string | undefined;
|
|
154
|
-
'skip-cert-verify': boolean;
|
|
155
|
-
udp: boolean;
|
|
156
|
-
network: string;
|
|
157
|
-
'ws-opts': {
|
|
158
|
-
path: string | undefined;
|
|
159
|
-
headers: Record<string, string> | undefined;
|
|
160
|
-
} | undefined;
|
|
161
|
-
} | {
|
|
162
|
-
name: string;
|
|
163
|
-
server: string;
|
|
164
|
-
port: number;
|
|
165
|
-
tfo: boolean | undefined;
|
|
166
|
-
'dialer-proxy': string | undefined;
|
|
167
|
-
'skip-cert-verify': boolean;
|
|
168
|
-
udp: boolean;
|
|
169
|
-
version: number;
|
|
170
|
-
token: string;
|
|
171
|
-
type: string;
|
|
172
|
-
sni: string | undefined;
|
|
173
|
-
uuid: string;
|
|
174
|
-
alpn: string[];
|
|
175
|
-
} | {
|
|
176
|
-
name: string;
|
|
177
|
-
server: string;
|
|
178
|
-
port: number;
|
|
179
|
-
tfo: boolean | undefined;
|
|
180
|
-
'dialer-proxy': string | undefined;
|
|
181
|
-
'skip-cert-verify': boolean;
|
|
182
|
-
udp: boolean;
|
|
183
|
-
version: number;
|
|
184
|
-
password: string;
|
|
185
|
-
type: string;
|
|
186
|
-
sni: string | undefined;
|
|
187
|
-
uuid: string;
|
|
188
|
-
alpn: string[];
|
|
189
|
-
} | {
|
|
190
|
-
name: string;
|
|
191
|
-
server: string;
|
|
192
|
-
port: number;
|
|
193
|
-
tfo: boolean | undefined;
|
|
194
|
-
'dialer-proxy': string | undefined;
|
|
195
|
-
type: string;
|
|
196
|
-
username: string;
|
|
197
|
-
password: string;
|
|
198
|
-
udp: boolean;
|
|
199
|
-
} | {
|
|
200
|
-
name: string;
|
|
201
|
-
server: string;
|
|
202
|
-
port: number;
|
|
203
|
-
tfo: boolean | undefined;
|
|
204
|
-
'dialer-proxy': string | undefined;
|
|
205
|
-
type: string;
|
|
206
|
-
username: string;
|
|
207
|
-
password: string;
|
|
208
|
-
} | {
|
|
209
|
-
name: string;
|
|
210
|
-
server: string;
|
|
211
|
-
port: number;
|
|
212
|
-
tfo: boolean | undefined;
|
|
213
|
-
'dialer-proxy': string | undefined;
|
|
214
|
-
alterId: number | undefined;
|
|
215
|
-
tls: boolean;
|
|
216
|
-
udp: boolean;
|
|
217
|
-
uuid: string;
|
|
218
|
-
servername: string | undefined;
|
|
219
|
-
cipher: string;
|
|
220
|
-
network: string;
|
|
221
|
-
'ws-opts': {
|
|
222
|
-
path: string | undefined;
|
|
223
|
-
headers: Record<string, string> | undefined;
|
|
224
|
-
} | undefined;
|
|
225
|
-
type: string;
|
|
226
|
-
} | {
|
|
227
|
-
name: string;
|
|
228
|
-
server: string;
|
|
229
|
-
port: number;
|
|
230
|
-
tfo: boolean | undefined;
|
|
231
|
-
'dialer-proxy': string | undefined;
|
|
232
|
-
type: string;
|
|
233
|
-
ports: string;
|
|
234
|
-
password: string;
|
|
235
|
-
down: string;
|
|
236
|
-
'skip-cert-verify': boolean;
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
declare const index$3_decode: typeof decode;
|
|
240
|
-
declare const index$3_encode: typeof encode;
|
|
241
|
-
declare namespace index$3 {
|
|
242
|
-
export {
|
|
243
|
-
index$3_decode as decode,
|
|
244
|
-
index$3_encode as encode,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
declare function decodeOne(sip002: string): ShadowSocksConfig;
|
|
249
|
-
declare function decodeBase64Multiline(text: string): string[];
|
|
250
|
-
declare function decodeMultiline(text: string): ShadowSocksConfig[];
|
|
251
|
-
|
|
252
|
-
declare const index$2_decodeBase64Multiline: typeof decodeBase64Multiline;
|
|
253
|
-
declare const index$2_decodeMultiline: typeof decodeMultiline;
|
|
254
|
-
declare const index$2_decodeOne: typeof decodeOne;
|
|
255
|
-
declare namespace index$2 {
|
|
256
|
-
export {
|
|
257
|
-
index$2_decodeBase64Multiline as decodeBase64Multiline,
|
|
258
|
-
index$2_decodeMultiline as decodeMultiline,
|
|
259
|
-
index$2_decodeOne as decodeOne,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
declare function parse$1(line: string): TrojanConfig;
|
|
264
|
-
|
|
265
|
-
declare namespace index$1 {
|
|
266
|
-
export {
|
|
267
|
-
parse$1 as parse,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
declare function parse(line: string): VmessConfig;
|
|
272
|
-
|
|
273
|
-
declare const index_parse: typeof parse;
|
|
274
|
-
declare namespace index {
|
|
275
|
-
export {
|
|
276
|
-
index_parse as parse,
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export { index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
|
|
281
|
-
export type { HttpProxyConfig, Hysteria2Config, ShadowSocksConfig, SharedConfigBase, SnellConfig, Socks5Config, SupportedConfig, TlsSharedConfig, TrojanBasicConfig, TrojanConfig, TuicConfig, TuicV5Config, VmessConfig };
|
package/dist/es/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{never as s}from"foxts/guard";import{stringJoin as e}from"foxts/string-join";import{uint8ArrayToString as r,base64ToUint8Array as t}from"foxts/uint8array-utils";let o=Number,p=s=>s.split(",").map(s=>s.trim());function a(s){let e=s.indexOf("=");return -1===e?["",""]:[s.slice(0,e).trim(),s.slice(e+1).trim()]}let n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),i=new Set(["version","download-bandwidth","port-hopping-interval","udp-port","shadow-tls-version"]),d=new Set([]),u=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token","underlying-proxy","shadow-tls-password","shadow-tls-sni"]),l=Symbol("unsupported");var w={__proto__:null,decode:function(s){let[e,r]=a(s),[t,w,c,...h]=p(r),y=o(c),m=Object.fromEntries(h.map(s=>{let[e,r]=a(s);return n.has(e)?[e,"true"===r]:i.has(e)?[e,o(r)]:d.has(e)?[e,p(r)]:u.has(e)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[e,r.slice(1,-1)]:[e,r]:[e,l]})),f={raw:s,name:e,server:w,port:y,tfo:m.tfo,blockQuic:m["block-quic"],underlyingProxy:m["underlying-proxy"]},v={sni:m.sni,skipCertVerify:m["skip-cert-verify"]};switch(t){case"snell":return{type:"snell",psk:m.psk,version:m.version,reuse:m.reuse,...f};case"ss":{let s=m["shadow-tls-password"],e=m["shadow-tls-sni"],r=m["shadow-tls-version"];return{type:"ss",cipher:m["encrypt-method"],password:m.password,udp:m["udp-relay"],obfs:m.obfs,obfsHost:m["obfs-host"],obfsUri:m["obfs-uri"],udpPort:m["udp-port"],shadowTlsPassword:s,shadowTlsSni:e,shadowTlsVersion:r,...f}}case"trojan":return{type:"trojan",password:m.password,udp:m["udp-relay"],ws:m.ws,wsPath:m["ws-path"],wsHeaders:m["ws-headers"],...v,...f};case"tuic":return{type:"tuic",uuid:m.uuid,alpn:m.alpn,token:m.token,...v,...f};case"tuic-v5":return{type:"tuic-v5",uuid:m.uuid,alpn:m.alpn,password:m.password,...v,...f};case"socks5":return{type:"socks5",username:h[0],password:h[1],udp:m["udp-relay"],...f};case"http":return{type:"http",username:h[0],password:h[1],...f};case"vmess":return{type:"vmess",username:m.username,tls:m.tls,vmessAead:m["vmess-aead"],ws:m.ws,wsPath:m["ws-path"],wsHeaders:m["ws-headers"],udp:m["udp-relay"],...v,...f};case"hysteria2":return{type:"hysteria2",password:m.password,skipCertVerify:m["skip-cert-verify"],downloadBandwidth:m["download-bandwidth"],portHopping:m["port-hopping"],portHoppingInterval:m["port-hopping-interval"],...f};default:throw TypeError(`Unsupported type: ${t} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`,r.underlyingProxy&&`underlying-proxy=${r.underlyingProxy}`];switch(r.type){case"snell":return e([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return e([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,r.shadowTlsPassword&&`shadow-tls-password=${r.shadowTlsPassword}`,r.shadowTlsSni&&`shadow-tls-sni=${r.shadowTlsSni}`,r.shadowTlsVersion&&`shadow-tls-version=${r.shadowTlsVersion}`,r.udp&&"udp-relay=true",r.udpPort&&`udp-port=${r.udpPort}`,r.obfs&&`obfs=${r.obfs}`,r.obfsHost&&`obfs-host=${r.obfsHost}`,r.obfsUri&&`obfs-uri=${r.obfsUri}`,...t],", ");case"trojan":return e([`${r.name} = trojan, ${r.server}, ${r.port}, password=${r.password}`,r.sni&&`sni=${r.sni}`,r.skipCertVerify&&"skip-cert-verify=true",...t,r.udp&&"udp-relay=true",r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`],", ");case"tuic":return e([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return e([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return e([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return e([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,r.ws&&"ws=true",r.wsPath&&`ws-path=${"/"===r.wsPath[0]?r.wsPath:`/${r.wsPath}`}`,r.wsHeaders&&`ws-headers=${r.wsHeaders}`,`skip-cert-verify=${r.skipCertVerify}`,`tfo=${r.tfo}`,`udp-relay=${r.udp}`],", ");case"hysteria2":return e([`${r.name} = hysteria2, ${r.server}, ${r.port}`,`password=${r.password}`,`download-bandwidth=${r.downloadBandwidth}`,r.portHopping&&`port-hopping="${r.portHopping}"`,r.portHoppingInterval&&`port-hopping-interval=${r.portHoppingInterval}`,`skip-cert-verify=${r.skipCertVerify}`,...t],", ");case"tuic-v5":return e([`${r.name} = tuic-v5, ${r.server}, ${r.port}`,`password=${r.password}`,`uuid=${r.uuid}`,`alpn=${r.alpn}`,`skip-cert-verify=${r.skipCertVerify}`,`sni=${r.sni}`,...t],", ");default:s(r,"type (surge encode)")}}};function c(s){return s.split(",").reduce((s,e)=>{let[r,t]=e.split(":"),o=t.trim();return(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),s[r.trim()]=o,s},{})}var h={__proto__:null,decode:function(s){if(!("type"in s)||"string"!=typeof s.type)throw TypeError("Missing or invalid type field");let e=JSON.stringify(s);switch(s.type){case"http":return{type:"http",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,underlyingProxy:s["dialer-proxy"],raw:e};case"ss":return{type:"ss",name:s.name,server:s.server,port:Number(s.port),cipher:s.cipher,password:s.password,udp:s.udp||!1,obfs:"obfs"===s.plugin?s["plugin-opts"].mode:void 0,underlyingProxy:s["dialer-proxy"],shadowTlsSni:"shadow-tls"===s.plugin?s["plugin-opts"].host:void 0,shadowTlsPassword:"shadow-tls"===s.plugin?s["plugin-opts"].password:void 0,shadowTlsVersion:"shadow-tls"===s.plugin?s["plugin-opts"].version:void 0,raw:e};case"socks5":return{type:"socks5",name:s.name,server:s.server,port:Number(s.port),username:s.username,password:s.password,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],raw:e};case"trojan":return{type:"trojan",name:s.name,server:s.server,port:Number(s.port),password:s.password,sni:s.sni,skipCertVerify:s["skip-cert-verify"]||!1,udp:s.udp||!1,underlyingProxy:s["dialer-proxy"],ws:"ws"===s.network,wsPath:s["ws-opts"]?.path,wsHeaders:s["ws-opts"]?.headers?Object.entries(s["ws-opts"]?.headers).map(([s,e])=>`${s}:${e}`).join(", "):void 0,raw:e};case"vmess":return{type:"vmess",name:s.name,server:s.server,port:Number(s.port),username:s.uuid,vmessAead:1===s.alterId||"1"===s.alterId,sni:s.servername,ws:"ws"===s.network,wsPath:s["ws-path"],wsHeaders:s["ws-headers"]?Object.entries(s["ws-headers"]).map(([s,e])=>`${s}:${e}`).join(", "):void 0,tls:s.tls||!1,udp:s.udp??!0,underlyingProxy:s["dialer-proxy"],raw:e,skipCertVerify:s["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${s.type} (clash decode)`)}},encode:function(e){let r={name:e.name,server:e.server,port:e.port,tfo:e.tfo,"dialer-proxy":e.underlyingProxy};switch(e.type){case"ss":if(e.shadowTlsPassword&&(e.udp||e.udpPort))throw Error("Clash doesn't support plain UDP for Shadow TLS (clash encode)");return{type:"ss",cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...e.shadowTlsPassword?{plugin:"shadow-tls","plugin-opts":{host:e.shadowTlsSni,password:e.shadowTlsPassword,version:e.shadowTlsVersion}}:{},...r};case"trojan":return{type:"trojan",password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?c(e.wsHeaders):void 0}:void 0,...r};case"tuic":case"tuic-v5":return{type:"tuic",sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(s=>s.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,version:"tuic"===e.type?4:"tuic-v5"===e.type?5:s(e),...r};case"socks5":return{type:"socks5",username:e.username,password:e.password,udp:e.udp,...r};case"http":return{type:"http",username:e.username,password:e.password,...r};case"vmess":return{alterId:e.vmessAead?0:void 0,tls:e.tls,udp:e.udp,uuid:e.username,servername:e.sni,cipher:"auto",network:e.ws?"ws":"tcp","ws-opts":e.ws?{path:e.wsPath,headers:e.wsHeaders?c(e.wsHeaders):void 0}:void 0,type:"vmess",...r};case"hysteria2":return{type:"hysteria2",ports:e.port+","+e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify,...r};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}};function y(s){let e,r,[t,p]=s.split("://");if("ss"!==t)throw Error(`[ss.decodeOne] Unsupported type: ${t}`);let[a,n]=p.split("@");a.includes(":")?[e,...r]=a.split(":",3):[e,...r]=atob(a).split(":",3),r=r.join(":");let[i,d]=n.split(":"),[u,l]=d.split("#"),[w,c]=u.split("/"),h=null;if(c)try{h=new URLSearchParams(c).get("plugin")}catch(e){let s=Error(`[ss.decodeOne] Invalid plugins: ${c}`);throw s.cause=e,s}let y=(h?.split(";")??[]).reduce((s,e)=>{let[r,t]=e.split("=");return s[r]=t,s},{});return{raw:s,type:"ss",name:decodeURIComponent(l),server:i,port:o(w),cipher:e,password:r,udp:!0,obfs:"obfs-local"in y&&"obfs"in y&&("http"===y.obfs||"tls"===y.obfs)?y.obfs:void 0,obfsHost:"obfs-host"in y?y["obfs-host"]:void 0}}function m(s){return atob(s).replaceAll("\r\n","\n").split("\n").filter(Boolean)}var f={__proto__:null,decodeBase64Multiline:m,decodeMultiline:function(s){return m(s).map(s=>y(s))},decodeOne:y},v={__proto__:null,parse:function(s){let e=new URL(s),r=e.username,t=e.hostname,o=Number.parseInt(e.port,10);return{raw:s,name:decodeURIComponent(e.hash.slice(1)),type:"trojan",server:t,port:o,password:r,udp:!0,sni:e.searchParams.get("sni")??t,skipCertVerify:!0}}},$={__proto__:null,parse:function(s){let e=JSON.parse(r(t(s.slice(8)))),o=e.ps,p=e.path;return{raw:s,name:o,server:e.add,port:Number.parseInt(e.port,10),type:"vmess",username:e.id,tls:e.tls,vmessAead:"0"===e.aid,sni:e.sni,ws:"ws"===e.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:e.sni||e.host?`Host:${e.sni||e.host}`:e.add,skipCertVerify:!0,udp:!0}}};export{h as clash,f as ss,w as surge,v as trojan,$ as vmess};
|