nodelistparser 1.0.3 → 1.1.1

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.
@@ -54,14 +54,12 @@ interface TrojanBasicConfig extends SharedConfigBase, TlsSharedConfig {
54
54
  }
55
55
  interface TuicConfig extends SharedConfigBase, TlsSharedConfig {
56
56
  type: 'tuic';
57
- sni: string;
58
57
  uuid: string;
59
58
  alpn: string;
60
59
  token: string;
61
60
  }
62
61
  interface TuicV5Config extends SharedConfigBase, TlsSharedConfig {
63
62
  type: 'tuic-v5';
64
- sni: string;
65
63
  uuid: string;
66
64
  alpn: string;
67
65
  password: string;
@@ -99,7 +97,10 @@ declare function decode$1(raw: string): SupportedConfig;
99
97
  declare function encode$1(config: SupportedConfig): string;
100
98
 
101
99
  declare namespace index$4 {
102
- export { decode$1 as decode, encode$1 as encode };
100
+ export {
101
+ decode$1 as decode,
102
+ encode$1 as encode,
103
+ };
103
104
  }
104
105
 
105
106
  declare function decode(config: Record<string, any>): SupportedConfig;
@@ -154,12 +155,13 @@ declare function encode(config: SupportedConfig): {
154
155
  tfo: boolean | undefined;
155
156
  'skip-cert-verify': boolean;
156
157
  udp: boolean;
158
+ version: number;
157
159
  token: string;
158
160
  name: string;
159
161
  type: string;
160
162
  server: string;
161
163
  port: number;
162
- sni: string;
164
+ sni: string | undefined;
163
165
  uuid: string;
164
166
  alpn: string[];
165
167
  alterId?: undefined;
@@ -177,12 +179,13 @@ declare function encode(config: SupportedConfig): {
177
179
  tfo: boolean | undefined;
178
180
  'skip-cert-verify': boolean;
179
181
  udp: boolean;
182
+ version: number;
180
183
  password: string;
181
184
  name: string;
182
185
  type: string;
183
186
  server: string;
184
187
  port: number;
185
- sni: string;
188
+ sni: string | undefined;
186
189
  uuid: string;
187
190
  alpn: string[];
188
191
  alterId?: undefined;
@@ -283,7 +286,10 @@ declare function encode(config: SupportedConfig): {
283
286
  declare const index$3_decode: typeof decode;
284
287
  declare const index$3_encode: typeof encode;
285
288
  declare namespace index$3 {
286
- export { index$3_decode as decode, index$3_encode as encode };
289
+ export {
290
+ index$3_decode as decode,
291
+ index$3_encode as encode,
292
+ };
287
293
  }
288
294
 
289
295
  declare function decodeOne(sip002: string): ShadowSocksConfig;
@@ -294,20 +300,29 @@ declare const index$2_decodeBase64Multiline: typeof decodeBase64Multiline;
294
300
  declare const index$2_decodeMultiline: typeof decodeMultiline;
295
301
  declare const index$2_decodeOne: typeof decodeOne;
296
302
  declare namespace index$2 {
297
- export { index$2_decodeBase64Multiline as decodeBase64Multiline, index$2_decodeMultiline as decodeMultiline, index$2_decodeOne as decodeOne };
303
+ export {
304
+ index$2_decodeBase64Multiline as decodeBase64Multiline,
305
+ index$2_decodeMultiline as decodeMultiline,
306
+ index$2_decodeOne as decodeOne,
307
+ };
298
308
  }
299
309
 
300
310
  declare function parse$1(line: string): TrojanConfig;
301
311
 
302
312
  declare namespace index$1 {
303
- export { parse$1 as parse };
313
+ export {
314
+ parse$1 as parse,
315
+ };
304
316
  }
305
317
 
306
318
  declare function parse(line: string): VmessConfig;
307
319
 
308
320
  declare const index_parse: typeof parse;
309
321
  declare namespace index {
310
- export { index_parse as parse };
322
+ export {
323
+ index_parse as parse,
324
+ };
311
325
  }
312
326
 
313
- export { type HttpProxyConfig, type Hysteria2Config, type ShadowSocksConfig, type SharedConfigBase, type SnellConfig, type Socks5Config, type SupportedConfig, type TrojanBasicConfig, type TrojanConfig, type TuicConfig, type TuicV5Config, type VmessConfig, index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
327
+ export { index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
328
+ export type { HttpProxyConfig, Hysteria2Config, ShadowSocksConfig, SharedConfigBase, SnellConfig, Socks5Config, SupportedConfig, TlsSharedConfig, TrojanBasicConfig, TrojanConfig, TuicConfig, TuicV5Config, VmessConfig };
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- var e=require("foxts/guard"),s=require("node:buffer");const r=e=>"true"===e,t=Number,p=e=>e.split(",").map(e=>e.trim());function o(e){let s=e.indexOf("=");return -1===s?["",""]:[e.slice(0,s).trim(),e.slice(s+1).trim()]}const n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),a=e=>n.has(e),i=new Set(["version","download-bandwidth","port-hopping-interval","udp-port"]),u=e=>i.has(e),d=new Set([]),c=e=>d.has(e),l=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token"]),w=e=>l.has(e),m=Symbol("unsupported"),f=e=>e.filter(Boolean).join(", ");function v(e){return e.split(",").reduce((e,s)=>{let[r,t]=s.split(":");return e[r.trim()]=t.trim(),e},{})}function y(e){let s,r;let[p,o]=e.split("://");if("ss"!==p)throw Error(`[ss.decodeOne] Unsupported type: ${p}`);let[n,a]=o.split("@");n.includes(":")?[s,r]=n.split(":"):[s,r]=atob(n).split(":");let[i,u]=a.split(":"),[d,c]=u.split("#"),[l,w]=d.split("/"),m=null;if(w)try{m=new URLSearchParams(w).get("plugin")}catch(s){let e=Error(`[ss.decodeOne] Invalid plugins: ${w}`);throw e.cause=s,e}let f=(m?.split(";")??[]).reduce((e,s)=>{let[r,t]=s.split("=");return e[r]=t,e},{});return{raw:e,type:"ss",name:decodeURIComponent(c),server:i,port:t(l),cipher:s,password:r,udp:!0,obfs:"obfs-local"in f&&"obfs"in f&&("http"===f.obfs||"tls"===f.obfs)?f.obfs:void 0,obfsHost:"obfs-host"in f?f["obfs-host"]:void 0}}function h(e){return atob(e).replaceAll("\r\n","\n").split("\n").filter(Boolean)}const $=new TextDecoder;exports.clash={__proto__:null,decode:function(e){if(!("type"in e)||"string"!=typeof e.type)throw TypeError("Missing or invalid type field");let s=JSON.stringify(e);switch(e.type){case"http":return{type:"http",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,raw:s};case"ss":return{type:"ss",name:e.name,server:e.server,port:Number(e.port),cipher:e.cipher,password:e.password,udp:e.udp||!1,obfs:"obfs"===e.plugin?e["plugin-opts"].mode:void 0,raw:s};case"socks5":return{type:"socks5",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,udp:e.udp||!1,raw:s};case"trojan":return{type:"trojan",name:e.name,server:e.server,port:Number(e.port),password:e.password,sni:e.sni,skipCertVerify:e["skip-cert-verify"]||!1,udp:e.udp||!1,raw:s};case"vmess":return{type:"vmess",name:e.name,server:e.server,port:Number(e.port),username:e.uuid,vmessAead:1===e.alterId||"1"===e.alterId,sni:e.servername,ws:"ws"===e.network,wsPath:e["ws-path"],wsHeaders:e["ws-headers"]?Object.entries(e["ws-headers"]).map(([e,s])=>`${e}:${s}`).join(", "):void 0,tls:e.tls||!1,udp:e.udp??!0,raw:s,skipCertVerify:e["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${e.type} (clash decode)`)}},encode:function(e){let s={tfo:e.tfo};switch(e.type){case"ss":return{name:e.name,type:"ss",server:e.server,port:e.port,cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...s};case"trojan":return{name:e.name,type:"trojan",server:e.server,port:e.port,password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,...s};case"tuic":case"tuic-v5":return{name:e.name,type:"tuic",server:e.server,port:e.port,sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(e=>e.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,...s};case"socks5":return{name:e.name,type:"socks5",server:e.server,port:e.port,username:e.username,password:e.password,udp:e.udp,...s};case"http":return{name:e.name,type:"http",server:e.server,port:e.port,username:e.username,password:e.password,...s};case"vmess":return{alterId:e.vmessAead?0:void 0,tls:e.tls,udp:e.udp,uuid:e.username,name:e.name,servername:e.sni,"ws-path":e.wsPath,server:e.server,"ws-headers":e.wsHeaders?v(e.wsHeaders):void 0,cipher:"auto","ws-opts":{path:e.wsPath,headers:e.wsHeaders?v(e.wsHeaders):void 0},type:"vmess",port:e.port,network:e.ws?"ws":"tcp"};case"hysteria2":return{name:e.name,type:"hysteria2",server:e.server,port:e.port,ports:e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}},exports.ss={__proto__:null,decodeBase64Multiline:h,decodeMultiline:function(e){return h(e).map(e=>y(e))},decodeOne:y},exports.surge={__proto__:null,decode:function(e){let[s,n]=o(e),[i,d,l,...f]=p(n),v=t(l),y=Object.fromEntries(f.map(e=>{let[s,n]=o(e);return a(s)?[s,r(n)]:u(s)?[s,t(n)]:c(s)?[s,p(n)]:w(s)?'"'===n[0]&&n.endsWith('"')||"'"===n[0]&&n.endsWith("'")?[s,n.slice(1,-1)]:[s,n]:[s,m]})),h={raw:e,name:s,server:d,port:v,tfo:y.tfo,blockQuic:y["block-quic"]};switch(i){case"snell":return{type:"snell",psk:y.psk,version:y.version,reuse:y.reuse,...h};case"ss":return{type:"ss",cipher:y["encrypt-method"],password:y.password,udp:y["udp-relay"],obfs:y.obfs,obfsHost:y["obfs-host"],obfsUri:y["obfs-uri"],udpPort:y["udp-port"],...h};case"trojan":return{type:"trojan",password:y.password,sni:y.sni,skipCertVerify:y["skip-cert-verify"],udp:y["udp-relay"],...h};case"tuic":return{type:"tuic",sni:y.sni,uuid:y.uuid,alpn:y.alpn,token:y.token,skipCertVerify:y["skip-cert-verify"],...h};case"tuic-v5":return{type:"tuic-v5",uuid:y.uuid,alpn:y.alpn,password:y.password,sni:y.sni,skipCertVerify:y["skip-cert-verify"],...h};case"socks5":return{type:"socks5",username:f[0],password:f[1],udp:y["udp-relay"],...h};case"http":return{type:"http",username:f[0],password:f[1],...h};case"vmess":return{type:"vmess",username:y.username,tls:y.tls,vmessAead:y["vmess-aead"],ws:y.ws,wsPath:y["ws-path"],wsHeaders:y["ws-headers"],skipCertVerify:y["skip-cert-verify"],udp:y["udp-relay"],sni:y.sni,...h};case"hysteria2":return{type:"hysteria2",password:y.password,skipCertVerify:y["skip-cert-verify"],downloadBandwidth:y["download-bandwidth"],portHopping:y["port-hopping"],portHoppingInterval:y["port-hopping-interval"],...h};default:throw TypeError(`Unsupported type: ${i} (surge decode)`)}},encode:function(s){let r=[s.tfo&&"tfo=true",s.blockQuic&&`block-quic=${s.blockQuic}`];switch(s.type){case"snell":return f([`${s.name} = snell, ${s.server}, ${s.port}, psk=${s.psk}, version=${s.version}, reuse=${s.reuse}`,...r]);case"ss":return f([`${s.name} = ss, ${s.server}, ${s.port}, encrypt-method=${s.cipher}, password=${s.password}`,s.udp&&"udp-relay=true",s.udpPort&&`udp-port=${s.udpPort}`,s.obfs&&`obfs=${s.obfs}`,s.obfsHost&&`obfs-host=${s.obfsHost}`,s.obfsUri&&`obfs-uri=${s.obfsUri}`,...r]);case"trojan":return f([`${s.name} = trojan, ${s.server}, ${s.port}, password=${s.password}`,s.sni&&`sni=${s.sni}`,s.skipCertVerify&&"skip-cert-verify=true",...r,s.udp&&"udp-relay=true"]);case"tuic":return f([`${s.name} = tuic, ${s.server}, ${s.port}, sni=${s.sni}, uuid=${s.uuid}, alpn=${s.alpn}, token=${s.token}`,...r]);case"socks5":return f([`${s.name} = socks5, ${s.server}, ${s.port}, ${s.username}, ${s.password}`,s.udp&&"udp-relay=true",...r]);case"http":return f([`${s.name} = http, ${s.server}, ${s.port}, ${s.username}, ${s.password}`,...r]);case"vmess":return f([`${s.name} = vmess, ${s.server}, ${s.port}`,`username=${s.username}`,`tls=${s.tls}`,`vmess-aead=${s.vmessAead}`,"ws=true",s.wsPath&&`ws-path=${"/"===s.wsPath[0]?s.wsPath:`/${s.wsPath}`}`,s.wsHeaders&&`ws-headers=${s.wsHeaders}`,`skip-cert-verify=${s.skipCertVerify}`,`tfo=${s.tfo}`,`udp-relay=${s.udp}`]);case"hysteria2":return f([`${s.name} = hysteria2, ${s.server}, ${s.port}`,`password=${s.password}`,`download-bandwidth=${s.downloadBandwidth}`,s.portHopping&&`port-hopping="${s.portHopping}"`,s.portHoppingInterval&&`port-hopping-interval=${s.portHoppingInterval}`,`skip-cert-verify=${s.skipCertVerify}`,...r]);case"tuic-v5":return f([`${s.name} = tuic-v5, ${s.server}, ${s.port}`,`password=${s.password}`,`uuid=${s.uuid}`,`alpn=${s.alpn}`,`skip-cert-verify=${s.skipCertVerify}`,`sni=${s.sni}`,...r]);default:e.never(s,"type (clash encode)")}}},exports.trojan={__proto__:null,parse:function(e){let s=new URL(e),r=s.username,t=s.hostname,p=Number.parseInt(s.port,10);if(Number.isNaN(p))throw TypeError("invalid port: "+s.port);return{raw:e,name:decodeURIComponent(s.hash.slice(1)),type:"trojan",server:t,port:p,password:r,udp:!0,sni:s.searchParams.get("sni")??t,skipCertVerify:!0}}},exports.vmess={__proto__:null,parse:function(e){let r=JSON.parse($.decode(s.Buffer.from(e.slice(8),"base64"))),t=r.ps,p=r.path;return{raw:e,name:t,server:r.add,port:Number.parseInt(r.port,10),type:"vmess",username:r.id,tls:r.tls,vmessAead:"0"===r.aid,sni:r.sni,ws:"ws"===r.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:r.sni||r.host?`Host:${r.sni||r.host}`:r.add,skipCertVerify:!0,udp:!0}}};
1
+ var e=require("foxts/guard"),s=require("foxts/string-join"),r=require("node:buffer");const t=Number,p=e=>e.split(",").map(e=>e.trim());function o(e){let s=e.indexOf("=");return -1===s?["",""]:[e.slice(0,s).trim(),e.slice(s+1).trim()]}const 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"]),i=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"]),d=Symbol("unsupported");function c(e){return e.split(",").reduce((e,s)=>{let[r,t]=s.split(":");return e[r.trim()]=t.trim(),e},{})}function l(e){let s,r,[p,o]=e.split("://");if("ss"!==p)throw Error(`[ss.decodeOne] Unsupported type: ${p}`);let[n,a]=o.split("@");n.includes(":")?[s,r]=n.split(":"):[s,r]=atob(n).split(":");let[i,u]=a.split(":"),[d,c]=u.split("#"),[l,w]=d.split("/"),m=null;if(w)try{m=new URLSearchParams(w).get("plugin")}catch(s){let e=Error(`[ss.decodeOne] Invalid plugins: ${w}`);throw e.cause=s,e}let f=(m?.split(";")??[]).reduce((e,s)=>{let[r,t]=s.split("=");return e[r]=t,e},{});return{raw:e,type:"ss",name:decodeURIComponent(c),server:i,port:t(l),cipher:s,password:r,udp:!0,obfs:"obfs-local"in f&&"obfs"in f&&("http"===f.obfs||"tls"===f.obfs)?f.obfs:void 0,obfsHost:"obfs-host"in f?f["obfs-host"]:void 0}}function w(e){return atob(e).replaceAll("\r\n","\n").split("\n").filter(Boolean)}const m=new TextDecoder;exports.clash={__proto__:null,decode:function(e){if(!("type"in e)||"string"!=typeof e.type)throw TypeError("Missing or invalid type field");let s=JSON.stringify(e);switch(e.type){case"http":return{type:"http",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,raw:s};case"ss":return{type:"ss",name:e.name,server:e.server,port:Number(e.port),cipher:e.cipher,password:e.password,udp:e.udp||!1,obfs:"obfs"===e.plugin?e["plugin-opts"].mode:void 0,raw:s};case"socks5":return{type:"socks5",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,udp:e.udp||!1,raw:s};case"trojan":return{type:"trojan",name:e.name,server:e.server,port:Number(e.port),password:e.password,sni:e.sni,skipCertVerify:e["skip-cert-verify"]||!1,udp:e.udp||!1,raw:s};case"vmess":return{type:"vmess",name:e.name,server:e.server,port:Number(e.port),username:e.uuid,vmessAead:1===e.alterId||"1"===e.alterId,sni:e.servername,ws:"ws"===e.network,wsPath:e["ws-path"],wsHeaders:e["ws-headers"]?Object.entries(e["ws-headers"]).map(([e,s])=>`${e}:${s}`).join(", "):void 0,tls:e.tls||!1,udp:e.udp??!0,raw:s,skipCertVerify:e["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${e.type} (clash decode)`)}},encode:function(s){let r={tfo:s.tfo};switch(s.type){case"ss":return{name:s.name,type:"ss",server:s.server,port:s.port,cipher:s.cipher,password:s.password,udp:s.udp,...s.obfs?{plugin:"obfs","plugin-opts":{mode:s.obfs,host:s.obfsHost,uri:s.obfsUri}}:{},...r};case"trojan":return{name:s.name,type:"trojan",server:s.server,port:s.port,password:s.password,sni:s.sni,"skip-cert-verify":s.skipCertVerify,udp:s.udp,...r};case"tuic":case"tuic-v5":return{name:s.name,type:"tuic",server:s.server,port:s.port,sni:s.sni,uuid:s.uuid,alpn:s.alpn.split(",").map(e=>e.trim()),..."tuic"===s.type?{token:s.token}:{password:s.password},"skip-cert-verify":s.skipCertVerify,udp:!0,version:"tuic"===s.type?4:"tuic-v5"===s.type?5:e.never(s),...r};case"socks5":return{name:s.name,type:"socks5",server:s.server,port:s.port,username:s.username,password:s.password,udp:s.udp,...r};case"http":return{name:s.name,type:"http",server:s.server,port:s.port,username:s.username,password:s.password,...r};case"vmess":return{alterId:s.vmessAead?0:void 0,tls:s.tls,udp:s.udp,uuid:s.username,name:s.name,servername:s.sni,"ws-path":s.wsPath,server:s.server,"ws-headers":s.wsHeaders?c(s.wsHeaders):void 0,cipher:"auto","ws-opts":{path:s.wsPath,headers:s.wsHeaders?c(s.wsHeaders):void 0},type:"vmess",port:s.port,network:s.ws?"ws":"tcp"};case"hysteria2":return{name:s.name,type:"hysteria2",server:s.server,port:s.port,ports:s.portHopping,password:s.password,down:s.downloadBandwidth+" Mbps","skip-cert-verify":s.skipCertVerify};default:throw TypeError(`Unsupported type: ${s.type} (clash encode)`)}}},exports.ss={__proto__:null,decodeBase64Multiline:w,decodeMultiline:function(e){return w(e).map(e=>l(e))},decodeOne:l},exports.surge={__proto__:null,decode:function(e){let[s,r]=o(e),[c,l,w,...m]=p(r),f=t(w),v=Object.fromEntries(m.map(e=>{let[s,r]=o(e);return n.has(s)?[s,"true"===r]:a.has(s)?[s,t(r)]:i.has(s)?[s,p(r)]:u.has(s)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[s,r.slice(1,-1)]:[s,r]:[s,d]})),h={raw:e,name:s,server:l,port:f,tfo:v.tfo,blockQuic:v["block-quic"]},y={sni:v.sni,skipCertVerify:v["skip-cert-verify"]};switch(c){case"snell":return{type:"snell",psk:v.psk,version:v.version,reuse:v.reuse,...h};case"ss":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"],...h};case"trojan":return{type:"trojan",password:v.password,udp:v["udp-relay"],...y,...h};case"tuic":return{type:"tuic",uuid:v.uuid,alpn:v.alpn,token:v.token,...y,...h};case"tuic-v5":return{type:"tuic-v5",uuid:v.uuid,alpn:v.alpn,password:v.password,...y,...h};case"socks5":return{type:"socks5",username:m[0],password:m[1],udp:v["udp-relay"],...h};case"http":return{type:"http",username:m[0],password:m[1],...h};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"],...y,...h};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"],...h};default:throw TypeError(`Unsupported type: ${c} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`];switch(r.type){case"snell":return s.stringJoin([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return s.stringJoin([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,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 s.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"],", ");case"tuic":return s.stringJoin([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return s.stringJoin([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return s.stringJoin([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return s.stringJoin([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,"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 s.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 s.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:e.never(r,"type (clash encode)")}}},exports.trojan={__proto__:null,parse:function(e){let s=new URL(e),r=s.username,t=s.hostname,p=Number.parseInt(s.port,10);if(Number.isNaN(p))throw TypeError("invalid port: "+s.port);return{raw:e,name:decodeURIComponent(s.hash.slice(1)),type:"trojan",server:t,port:p,password:r,udp:!0,sni:s.searchParams.get("sni")??t,skipCertVerify:!0}}},exports.vmess={__proto__:null,parse:function(e){let s=JSON.parse(m.decode(r.Buffer.from(e.slice(8),"base64"))),t=s.ps,p=s.path;return{raw:e,name:t,server:s.add,port:Number.parseInt(s.port,10),type:"vmess",username:s.id,tls:s.tls,vmessAead:"0"===s.aid,sni:s.sni,ws:"ws"===s.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:s.sni||s.host?`Host:${s.sni||s.host}`:s.add,skipCertVerify:!0,udp:!0}}};
@@ -54,14 +54,12 @@ interface TrojanBasicConfig extends SharedConfigBase, TlsSharedConfig {
54
54
  }
55
55
  interface TuicConfig extends SharedConfigBase, TlsSharedConfig {
56
56
  type: 'tuic';
57
- sni: string;
58
57
  uuid: string;
59
58
  alpn: string;
60
59
  token: string;
61
60
  }
62
61
  interface TuicV5Config extends SharedConfigBase, TlsSharedConfig {
63
62
  type: 'tuic-v5';
64
- sni: string;
65
63
  uuid: string;
66
64
  alpn: string;
67
65
  password: string;
@@ -99,7 +97,10 @@ declare function decode$1(raw: string): SupportedConfig;
99
97
  declare function encode$1(config: SupportedConfig): string;
100
98
 
101
99
  declare namespace index$4 {
102
- export { decode$1 as decode, encode$1 as encode };
100
+ export {
101
+ decode$1 as decode,
102
+ encode$1 as encode,
103
+ };
103
104
  }
104
105
 
105
106
  declare function decode(config: Record<string, any>): SupportedConfig;
@@ -154,12 +155,13 @@ declare function encode(config: SupportedConfig): {
154
155
  tfo: boolean | undefined;
155
156
  'skip-cert-verify': boolean;
156
157
  udp: boolean;
158
+ version: number;
157
159
  token: string;
158
160
  name: string;
159
161
  type: string;
160
162
  server: string;
161
163
  port: number;
162
- sni: string;
164
+ sni: string | undefined;
163
165
  uuid: string;
164
166
  alpn: string[];
165
167
  alterId?: undefined;
@@ -177,12 +179,13 @@ declare function encode(config: SupportedConfig): {
177
179
  tfo: boolean | undefined;
178
180
  'skip-cert-verify': boolean;
179
181
  udp: boolean;
182
+ version: number;
180
183
  password: string;
181
184
  name: string;
182
185
  type: string;
183
186
  server: string;
184
187
  port: number;
185
- sni: string;
188
+ sni: string | undefined;
186
189
  uuid: string;
187
190
  alpn: string[];
188
191
  alterId?: undefined;
@@ -283,7 +286,10 @@ declare function encode(config: SupportedConfig): {
283
286
  declare const index$3_decode: typeof decode;
284
287
  declare const index$3_encode: typeof encode;
285
288
  declare namespace index$3 {
286
- export { index$3_decode as decode, index$3_encode as encode };
289
+ export {
290
+ index$3_decode as decode,
291
+ index$3_encode as encode,
292
+ };
287
293
  }
288
294
 
289
295
  declare function decodeOne(sip002: string): ShadowSocksConfig;
@@ -294,20 +300,29 @@ declare const index$2_decodeBase64Multiline: typeof decodeBase64Multiline;
294
300
  declare const index$2_decodeMultiline: typeof decodeMultiline;
295
301
  declare const index$2_decodeOne: typeof decodeOne;
296
302
  declare namespace index$2 {
297
- export { index$2_decodeBase64Multiline as decodeBase64Multiline, index$2_decodeMultiline as decodeMultiline, index$2_decodeOne as decodeOne };
303
+ export {
304
+ index$2_decodeBase64Multiline as decodeBase64Multiline,
305
+ index$2_decodeMultiline as decodeMultiline,
306
+ index$2_decodeOne as decodeOne,
307
+ };
298
308
  }
299
309
 
300
310
  declare function parse$1(line: string): TrojanConfig;
301
311
 
302
312
  declare namespace index$1 {
303
- export { parse$1 as parse };
313
+ export {
314
+ parse$1 as parse,
315
+ };
304
316
  }
305
317
 
306
318
  declare function parse(line: string): VmessConfig;
307
319
 
308
320
  declare const index_parse: typeof parse;
309
321
  declare namespace index {
310
- export { index_parse as parse };
322
+ export {
323
+ index_parse as parse,
324
+ };
311
325
  }
312
326
 
313
- export { type HttpProxyConfig, type Hysteria2Config, type ShadowSocksConfig, type SharedConfigBase, type SnellConfig, type Socks5Config, type SupportedConfig, type TrojanBasicConfig, type TrojanConfig, type TuicConfig, type TuicV5Config, type VmessConfig, index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
327
+ export { index$3 as clash, index$2 as ss, index$4 as surge, index$1 as trojan, index as vmess };
328
+ export type { HttpProxyConfig, Hysteria2Config, ShadowSocksConfig, SharedConfigBase, SnellConfig, Socks5Config, SupportedConfig, TlsSharedConfig, TrojanBasicConfig, TrojanConfig, TuicConfig, TuicV5Config, VmessConfig };
package/dist/es/index.mjs CHANGED
@@ -1 +1 @@
1
- import{never as e}from"foxts/guard";import{Buffer as s}from"node:buffer";let r=e=>"true"===e,t=Number,p=e=>e.split(",").map(e=>e.trim());function o(e){let s=e.indexOf("=");return -1===s?["",""]:[e.slice(0,s).trim(),e.slice(s+1).trim()]}let n=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),a=e=>n.has(e),i=new Set(["version","download-bandwidth","port-hopping-interval","udp-port"]),d=e=>i.has(e),u=new Set([]),l=e=>u.has(e),c=new Set(["username","password","sni","encrypt-method","psk","obfs","obfs-host","uuid","alpn","block-quic","ws-path","ws-headers","port-hopping","token"]),w=e=>c.has(e),m=Symbol("unsupported"),f=e=>e.filter(Boolean).join(", ");var v={__proto__:null,decode:function(e){let[s,n]=o(e),[i,u,c,...f]=p(n),v=t(c),y=Object.fromEntries(f.map(e=>{let[s,n]=o(e);return a(s)?[s,r(n)]:d(s)?[s,t(n)]:l(s)?[s,p(n)]:w(s)?'"'===n[0]&&n.endsWith('"')||"'"===n[0]&&n.endsWith("'")?[s,n.slice(1,-1)]:[s,n]:[s,m]})),h={raw:e,name:s,server:u,port:v,tfo:y.tfo,blockQuic:y["block-quic"]};switch(i){case"snell":return{type:"snell",psk:y.psk,version:y.version,reuse:y.reuse,...h};case"ss":return{type:"ss",cipher:y["encrypt-method"],password:y.password,udp:y["udp-relay"],obfs:y.obfs,obfsHost:y["obfs-host"],obfsUri:y["obfs-uri"],udpPort:y["udp-port"],...h};case"trojan":return{type:"trojan",password:y.password,sni:y.sni,skipCertVerify:y["skip-cert-verify"],udp:y["udp-relay"],...h};case"tuic":return{type:"tuic",sni:y.sni,uuid:y.uuid,alpn:y.alpn,token:y.token,skipCertVerify:y["skip-cert-verify"],...h};case"tuic-v5":return{type:"tuic-v5",uuid:y.uuid,alpn:y.alpn,password:y.password,sni:y.sni,skipCertVerify:y["skip-cert-verify"],...h};case"socks5":return{type:"socks5",username:f[0],password:f[1],udp:y["udp-relay"],...h};case"http":return{type:"http",username:f[0],password:f[1],...h};case"vmess":return{type:"vmess",username:y.username,tls:y.tls,vmessAead:y["vmess-aead"],ws:y.ws,wsPath:y["ws-path"],wsHeaders:y["ws-headers"],skipCertVerify:y["skip-cert-verify"],udp:y["udp-relay"],sni:y.sni,...h};case"hysteria2":return{type:"hysteria2",password:y.password,skipCertVerify:y["skip-cert-verify"],downloadBandwidth:y["download-bandwidth"],portHopping:y["port-hopping"],portHoppingInterval:y["port-hopping-interval"],...h};default:throw TypeError(`Unsupported type: ${i} (surge decode)`)}},encode:function(s){let r=[s.tfo&&"tfo=true",s.blockQuic&&`block-quic=${s.blockQuic}`];switch(s.type){case"snell":return f([`${s.name} = snell, ${s.server}, ${s.port}, psk=${s.psk}, version=${s.version}, reuse=${s.reuse}`,...r]);case"ss":return f([`${s.name} = ss, ${s.server}, ${s.port}, encrypt-method=${s.cipher}, password=${s.password}`,s.udp&&"udp-relay=true",s.udpPort&&`udp-port=${s.udpPort}`,s.obfs&&`obfs=${s.obfs}`,s.obfsHost&&`obfs-host=${s.obfsHost}`,s.obfsUri&&`obfs-uri=${s.obfsUri}`,...r]);case"trojan":return f([`${s.name} = trojan, ${s.server}, ${s.port}, password=${s.password}`,s.sni&&`sni=${s.sni}`,s.skipCertVerify&&"skip-cert-verify=true",...r,s.udp&&"udp-relay=true"]);case"tuic":return f([`${s.name} = tuic, ${s.server}, ${s.port}, sni=${s.sni}, uuid=${s.uuid}, alpn=${s.alpn}, token=${s.token}`,...r]);case"socks5":return f([`${s.name} = socks5, ${s.server}, ${s.port}, ${s.username}, ${s.password}`,s.udp&&"udp-relay=true",...r]);case"http":return f([`${s.name} = http, ${s.server}, ${s.port}, ${s.username}, ${s.password}`,...r]);case"vmess":return f([`${s.name} = vmess, ${s.server}, ${s.port}`,`username=${s.username}`,`tls=${s.tls}`,`vmess-aead=${s.vmessAead}`,"ws=true",s.wsPath&&`ws-path=${"/"===s.wsPath[0]?s.wsPath:`/${s.wsPath}`}`,s.wsHeaders&&`ws-headers=${s.wsHeaders}`,`skip-cert-verify=${s.skipCertVerify}`,`tfo=${s.tfo}`,`udp-relay=${s.udp}`]);case"hysteria2":return f([`${s.name} = hysteria2, ${s.server}, ${s.port}`,`password=${s.password}`,`download-bandwidth=${s.downloadBandwidth}`,s.portHopping&&`port-hopping="${s.portHopping}"`,s.portHoppingInterval&&`port-hopping-interval=${s.portHoppingInterval}`,`skip-cert-verify=${s.skipCertVerify}`,...r]);case"tuic-v5":return f([`${s.name} = tuic-v5, ${s.server}, ${s.port}`,`password=${s.password}`,`uuid=${s.uuid}`,`alpn=${s.alpn}`,`skip-cert-verify=${s.skipCertVerify}`,`sni=${s.sni}`,...r]);default:e(s,"type (clash encode)")}}};function y(e){return e.split(",").reduce((e,s)=>{let[r,t]=s.split(":");return e[r.trim()]=t.trim(),e},{})}var h={__proto__:null,decode:function(e){if(!("type"in e)||"string"!=typeof e.type)throw TypeError("Missing or invalid type field");let s=JSON.stringify(e);switch(e.type){case"http":return{type:"http",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,raw:s};case"ss":return{type:"ss",name:e.name,server:e.server,port:Number(e.port),cipher:e.cipher,password:e.password,udp:e.udp||!1,obfs:"obfs"===e.plugin?e["plugin-opts"].mode:void 0,raw:s};case"socks5":return{type:"socks5",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,udp:e.udp||!1,raw:s};case"trojan":return{type:"trojan",name:e.name,server:e.server,port:Number(e.port),password:e.password,sni:e.sni,skipCertVerify:e["skip-cert-verify"]||!1,udp:e.udp||!1,raw:s};case"vmess":return{type:"vmess",name:e.name,server:e.server,port:Number(e.port),username:e.uuid,vmessAead:1===e.alterId||"1"===e.alterId,sni:e.servername,ws:"ws"===e.network,wsPath:e["ws-path"],wsHeaders:e["ws-headers"]?Object.entries(e["ws-headers"]).map(([e,s])=>`${e}:${s}`).join(", "):void 0,tls:e.tls||!1,udp:e.udp??!0,raw:s,skipCertVerify:e["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${e.type} (clash decode)`)}},encode:function(e){let s={tfo:e.tfo};switch(e.type){case"ss":return{name:e.name,type:"ss",server:e.server,port:e.port,cipher:e.cipher,password:e.password,udp:e.udp,...e.obfs?{plugin:"obfs","plugin-opts":{mode:e.obfs,host:e.obfsHost,uri:e.obfsUri}}:{},...s};case"trojan":return{name:e.name,type:"trojan",server:e.server,port:e.port,password:e.password,sni:e.sni,"skip-cert-verify":e.skipCertVerify,udp:e.udp,...s};case"tuic":case"tuic-v5":return{name:e.name,type:"tuic",server:e.server,port:e.port,sni:e.sni,uuid:e.uuid,alpn:e.alpn.split(",").map(e=>e.trim()),..."tuic"===e.type?{token:e.token}:{password:e.password},"skip-cert-verify":e.skipCertVerify,udp:!0,...s};case"socks5":return{name:e.name,type:"socks5",server:e.server,port:e.port,username:e.username,password:e.password,udp:e.udp,...s};case"http":return{name:e.name,type:"http",server:e.server,port:e.port,username:e.username,password:e.password,...s};case"vmess":return{alterId:e.vmessAead?0:void 0,tls:e.tls,udp:e.udp,uuid:e.username,name:e.name,servername:e.sni,"ws-path":e.wsPath,server:e.server,"ws-headers":e.wsHeaders?y(e.wsHeaders):void 0,cipher:"auto","ws-opts":{path:e.wsPath,headers:e.wsHeaders?y(e.wsHeaders):void 0},type:"vmess",port:e.port,network:e.ws?"ws":"tcp"};case"hysteria2":return{name:e.name,type:"hysteria2",server:e.server,port:e.port,ports:e.portHopping,password:e.password,down:e.downloadBandwidth+" Mbps","skip-cert-verify":e.skipCertVerify};default:throw TypeError(`Unsupported type: ${e.type} (clash encode)`)}}};function $(e){let s,r;let[p,o]=e.split("://");if("ss"!==p)throw Error(`[ss.decodeOne] Unsupported type: ${p}`);let[n,a]=o.split("@");n.includes(":")?[s,r]=n.split(":"):[s,r]=atob(n).split(":");let[i,d]=a.split(":"),[u,l]=d.split("#"),[c,w]=u.split("/"),m=null;if(w)try{m=new URLSearchParams(w).get("plugin")}catch(s){let e=Error(`[ss.decodeOne] Invalid plugins: ${w}`);throw e.cause=s,e}let f=(m?.split(";")??[]).reduce((e,s)=>{let[r,t]=s.split("=");return e[r]=t,e},{});return{raw:e,type:"ss",name:decodeURIComponent(l),server:i,port:t(c),cipher:s,password:r,udp:!0,obfs:"obfs-local"in f&&"obfs"in f&&("http"===f.obfs||"tls"===f.obfs)?f.obfs:void 0,obfsHost:"obfs-host"in f?f["obfs-host"]:void 0}}function b(e){return atob(e).replaceAll("\r\n","\n").split("\n").filter(Boolean)}var k={__proto__:null,decodeBase64Multiline:b,decodeMultiline:function(e){return b(e).map(e=>$(e))},decodeOne:$},g={__proto__:null,parse:function(e){let s=new URL(e),r=s.username,t=s.hostname,p=Number.parseInt(s.port,10);if(Number.isNaN(p))throw TypeError("invalid port: "+s.port);return{raw:e,name:decodeURIComponent(s.hash.slice(1)),type:"trojan",server:t,port:p,password:r,udp:!0,sni:s.searchParams.get("sni")??t,skipCertVerify:!0}}};let H=new TextDecoder;var _={__proto__:null,parse:function(e){let r=JSON.parse(H.decode(s.from(e.slice(8),"base64"))),t=r.ps,p=r.path;return{raw:e,name:t,server:r.add,port:Number.parseInt(r.port,10),type:"vmess",username:r.id,tls:r.tls,vmessAead:"0"===r.aid,sni:r.sni,ws:"ws"===r.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:r.sni||r.host?`Host:${r.sni||r.host}`:r.add,skipCertVerify:!0,udp:!0}}};export{h as clash,k as ss,v as surge,g as trojan,_ as vmess};
1
+ import{never as e}from"foxts/guard";import{stringJoin as s}from"foxts/string-join";import{Buffer as r}from"node:buffer";let t=Number,p=e=>e.split(",").map(e=>e.trim());function o(e){let s=e.indexOf("=");return -1===s?["",""]:[e.slice(0,s).trim(),e.slice(s+1).trim()]}let a=new Set(["udp-relay","tfo","reuse","skip-cert-verify","tls","vmess-aead","ws"]),n=new Set(["version","download-bandwidth","port-hopping-interval","udp-port"]),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"]),u=Symbol("unsupported");var c={__proto__:null,decode:function(e){let[s,r]=o(e),[c,l,w,...m]=p(r),f=t(w),v=Object.fromEntries(m.map(e=>{let[s,r]=o(e);return a.has(s)?[s,"true"===r]:n.has(s)?[s,t(r)]:i.has(s)?[s,p(r)]:d.has(s)?'"'===r[0]&&r.endsWith('"')||"'"===r[0]&&r.endsWith("'")?[s,r.slice(1,-1)]:[s,r]:[s,u]})),h={raw:e,name:s,server:l,port:f,tfo:v.tfo,blockQuic:v["block-quic"]},y={sni:v.sni,skipCertVerify:v["skip-cert-verify"]};switch(c){case"snell":return{type:"snell",psk:v.psk,version:v.version,reuse:v.reuse,...h};case"ss":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"],...h};case"trojan":return{type:"trojan",password:v.password,udp:v["udp-relay"],...y,...h};case"tuic":return{type:"tuic",uuid:v.uuid,alpn:v.alpn,token:v.token,...y,...h};case"tuic-v5":return{type:"tuic-v5",uuid:v.uuid,alpn:v.alpn,password:v.password,...y,...h};case"socks5":return{type:"socks5",username:m[0],password:m[1],udp:v["udp-relay"],...h};case"http":return{type:"http",username:m[0],password:m[1],...h};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"],...y,...h};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"],...h};default:throw TypeError(`Unsupported type: ${c} (surge decode)`)}},encode:function(r){let t=[r.tfo&&"tfo=true",r.blockQuic&&`block-quic=${r.blockQuic}`];switch(r.type){case"snell":return s([`${r.name} = snell, ${r.server}, ${r.port}, psk=${r.psk}, version=${r.version}, reuse=${r.reuse}`,...t],", ");case"ss":return s([`${r.name} = ss, ${r.server}, ${r.port}, encrypt-method=${r.cipher}, password=${r.password}`,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 s([`${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"],", ");case"tuic":return s([`${r.name} = tuic, ${r.server}, ${r.port}, sni=${r.sni}, uuid=${r.uuid}, alpn=${r.alpn}, token=${r.token}`,...t],", ");case"socks5":return s([`${r.name} = socks5, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,r.udp&&"udp-relay=true",...t],", ");case"http":return s([`${r.name} = http, ${r.server}, ${r.port}, ${r.username}, ${r.password}`,...t],", ");case"vmess":return s([`${r.name} = vmess, ${r.server}, ${r.port}`,`username=${r.username}`,`tls=${r.tls}`,`vmess-aead=${r.vmessAead}`,"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 s([`${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 s([`${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:e(r,"type (clash encode)")}}};function l(e){return e.split(",").reduce((e,s)=>{let[r,t]=s.split(":");return e[r.trim()]=t.trim(),e},{})}var w={__proto__:null,decode:function(e){if(!("type"in e)||"string"!=typeof e.type)throw TypeError("Missing or invalid type field");let s=JSON.stringify(e);switch(e.type){case"http":return{type:"http",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,raw:s};case"ss":return{type:"ss",name:e.name,server:e.server,port:Number(e.port),cipher:e.cipher,password:e.password,udp:e.udp||!1,obfs:"obfs"===e.plugin?e["plugin-opts"].mode:void 0,raw:s};case"socks5":return{type:"socks5",name:e.name,server:e.server,port:Number(e.port),username:e.username,password:e.password,udp:e.udp||!1,raw:s};case"trojan":return{type:"trojan",name:e.name,server:e.server,port:Number(e.port),password:e.password,sni:e.sni,skipCertVerify:e["skip-cert-verify"]||!1,udp:e.udp||!1,raw:s};case"vmess":return{type:"vmess",name:e.name,server:e.server,port:Number(e.port),username:e.uuid,vmessAead:1===e.alterId||"1"===e.alterId,sni:e.servername,ws:"ws"===e.network,wsPath:e["ws-path"],wsHeaders:e["ws-headers"]?Object.entries(e["ws-headers"]).map(([e,s])=>`${e}:${s}`).join(", "):void 0,tls:e.tls||!1,udp:e.udp??!0,raw:s,skipCertVerify:e["skip-cert-verify"]||!1};default:throw TypeError(`Unsupported type: ${e.type} (clash decode)`)}},encode:function(s){let r={tfo:s.tfo};switch(s.type){case"ss":return{name:s.name,type:"ss",server:s.server,port:s.port,cipher:s.cipher,password:s.password,udp:s.udp,...s.obfs?{plugin:"obfs","plugin-opts":{mode:s.obfs,host:s.obfsHost,uri:s.obfsUri}}:{},...r};case"trojan":return{name:s.name,type:"trojan",server:s.server,port:s.port,password:s.password,sni:s.sni,"skip-cert-verify":s.skipCertVerify,udp:s.udp,...r};case"tuic":case"tuic-v5":return{name:s.name,type:"tuic",server:s.server,port:s.port,sni:s.sni,uuid:s.uuid,alpn:s.alpn.split(",").map(e=>e.trim()),..."tuic"===s.type?{token:s.token}:{password:s.password},"skip-cert-verify":s.skipCertVerify,udp:!0,version:"tuic"===s.type?4:"tuic-v5"===s.type?5:e(s),...r};case"socks5":return{name:s.name,type:"socks5",server:s.server,port:s.port,username:s.username,password:s.password,udp:s.udp,...r};case"http":return{name:s.name,type:"http",server:s.server,port:s.port,username:s.username,password:s.password,...r};case"vmess":return{alterId:s.vmessAead?0:void 0,tls:s.tls,udp:s.udp,uuid:s.username,name:s.name,servername:s.sni,"ws-path":s.wsPath,server:s.server,"ws-headers":s.wsHeaders?l(s.wsHeaders):void 0,cipher:"auto","ws-opts":{path:s.wsPath,headers:s.wsHeaders?l(s.wsHeaders):void 0},type:"vmess",port:s.port,network:s.ws?"ws":"tcp"};case"hysteria2":return{name:s.name,type:"hysteria2",server:s.server,port:s.port,ports:s.portHopping,password:s.password,down:s.downloadBandwidth+" Mbps","skip-cert-verify":s.skipCertVerify};default:throw TypeError(`Unsupported type: ${s.type} (clash encode)`)}}};function m(e){let s,r,[p,o]=e.split("://");if("ss"!==p)throw Error(`[ss.decodeOne] Unsupported type: ${p}`);let[a,n]=o.split("@");a.includes(":")?[s,r]=a.split(":"):[s,r]=atob(a).split(":");let[i,d]=n.split(":"),[u,c]=d.split("#"),[l,w]=u.split("/"),m=null;if(w)try{m=new URLSearchParams(w).get("plugin")}catch(s){let e=Error(`[ss.decodeOne] Invalid plugins: ${w}`);throw e.cause=s,e}let f=(m?.split(";")??[]).reduce((e,s)=>{let[r,t]=s.split("=");return e[r]=t,e},{});return{raw:e,type:"ss",name:decodeURIComponent(c),server:i,port:t(l),cipher:s,password:r,udp:!0,obfs:"obfs-local"in f&&"obfs"in f&&("http"===f.obfs||"tls"===f.obfs)?f.obfs:void 0,obfsHost:"obfs-host"in f?f["obfs-host"]:void 0}}function f(e){return atob(e).replaceAll("\r\n","\n").split("\n").filter(Boolean)}var v={__proto__:null,decodeBase64Multiline:f,decodeMultiline:function(e){return f(e).map(e=>m(e))},decodeOne:m},h={__proto__:null,parse:function(e){let s=new URL(e),r=s.username,t=s.hostname,p=Number.parseInt(s.port,10);if(Number.isNaN(p))throw TypeError("invalid port: "+s.port);return{raw:e,name:decodeURIComponent(s.hash.slice(1)),type:"trojan",server:t,port:p,password:r,udp:!0,sni:s.searchParams.get("sni")??t,skipCertVerify:!0}}};let y=new TextDecoder;var $={__proto__:null,parse:function(e){let s=JSON.parse(y.decode(r.from(e.slice(8),"base64"))),t=s.ps,p=s.path;return{raw:e,name:t,server:s.add,port:Number.parseInt(s.port,10),type:"vmess",username:s.id,tls:s.tls,vmessAead:"0"===s.aid,sni:s.sni,ws:"ws"===s.net,wsPath:"/"===p[0]?p:`/${p}`,wsHeaders:s.sni||s.host?`Host:${s.sni||s.host}`:s.add,skipCertVerify:!0,udp:!0}}};export{w as clash,v as ss,c as surge,h as trojan,$ as vmess};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodelistparser",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "description": "Surge / Mihomo (Clash.Meta) nodelist / proxy provider parser and generator.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,28 +34,28 @@
34
34
  "author": "Sukka <https://skk.moe>",
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "foxts": "^1.5.1"
37
+ "foxts": "^3.8.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@eslint-sukka/node": "^6.16.1",
41
- "@swc-node/register": "^1.10.9",
42
- "@swc/core": "^1.11.8",
40
+ "@eslint-sukka/node": "^6.22.1",
41
+ "@swc-node/register": "^1.10.10",
42
+ "@swc/core": "^1.12.11",
43
43
  "@types/mocha": "^10.0.10",
44
- "@types/node": "^22.13.10",
45
- "bumpp": "^10.0.3",
46
- "bunchee": "^6.4.0",
47
- "eslint": "^9.22.0",
48
- "eslint-config-sukka": "^6.16.1",
49
- "eslint-formatter-sukka": "^6.16.1",
50
- "expect": "^29.7.0",
51
- "mocha": "^11.1.0",
52
- "typescript": "^5.8.2"
44
+ "@types/node": "^22.16.2",
45
+ "bumpp": "^10.2.0",
46
+ "bunchee": "^6.5.4",
47
+ "eslint": "^9.30.1",
48
+ "eslint-config-sukka": "^6.22.1",
49
+ "eslint-formatter-sukka": "^6.22.1",
50
+ "expect": "^30.0.4",
51
+ "mocha": "^11.7.1",
52
+ "typescript": "^5.8.3"
53
53
  },
54
54
  "scripts": {
55
55
  "lint": "eslint --format=sukka .",
56
56
  "build": "bunchee --minify --no-sourcemap",
57
57
  "test": "mocha --require @swc-node/register src/*.test.ts src/**/*.test.ts",
58
- "prerelease": "pnpm run lint && pnpm run build",
58
+ "prerelease": "pnpm run lint && pnpm run test && pnpm run build",
59
59
  "release": "bumpp -r --all --commit \"release: %s\" --tag \"%s\""
60
60
  }
61
61
  }