@liblaf/sub-store 0.1.9 β†’ 0.1.11

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{run as Ee}from"@stricli/core";import{buildApplication as Re,buildRouteMap as Ze}from"@stricli/core";var V="",K="0.1.9";import be from"fs/promises";import{buildCommand as Ae}from"@stricli/core";import ve from"consola";import oe from"world-countries";var p={name:{common:"Unknown"},cca2:"UN",flag:"\uD83C\uDDFA\uD83C\uDDF3"};function w(e){return oe.find((o)=>o.cca2===e)}class E{provider;connection=!1;country=p;emby=!1;info=!1;multiplier=1;constructor(e){this.provider=e}get prettyName(){let e=this.name;if(this.provider.name==="JMS"){let o=this.name.match(/@(?<name>[\w-]+)/);if(o)e=o.groups?.name??this.name}if(e.startsWith("\u3010"))return`[${this.provider.name}]${e}`;return`[${this.provider.name}] ${e}`}}import s from"zod";var h=s.looseObject({name:s.string(),type:s.string(),server:s.string()}),y=s.looseObject({name:s.string(),type:s.enum(["select","url-test"]),proxies:s.array(s.string()),url:s.url().default("https://cp.cloudflare.com"),lazy:s.boolean().default(!0),"expected-status":s.int().min(100).max(599).default(204),icon:s.url().optional()}),x=s.looseObject({proxies:s.array(h).optional(),"proxy-groups":s.array(y).optional()});class u extends E{raw;constructor(e,o){super(o);this.raw=h.parse(e)}get name(){return this.raw.name}get type(){return this.raw.type}get server(){return this.raw.server}get mihomo(){return{...this.raw,name:this.prettyName}}}import re from"yaml";function f(e){let o=re.parse(e,{merge:!0});return x.parse(o)}import te from"fs/promises";import*as g from"remeda";import ie from"yaml";class d{template;static async load(e){let o=await te.readFile(e,"utf8");return new d(o)}constructor(e){this.template=f(e)}render(e,o){let r=g.clone(this.template);r.proxies=e.map((i)=>i.mihomo);let t=this.renderGroupProxy();r["proxy-groups"]=[t];for(let i of o){let m=this.renderGroup(e,i);if(!m)continue;r["proxy-groups"].push(m),t.proxies.push(m.name)}return r=this.sanitize(r),ie.stringify(r,{aliasDuplicateObjects:!1})}sanitize(e){return e=g.omitBy(e,(o,r)=>r.startsWith("__")),e}renderGroup(e,o){let r=e.filter(o.filter);if(r.length===0)return;let t=r.map((m)=>m.prettyName),i={name:o.name,type:o.type,proxies:t,url:o.url,icon:o.icon};return y.parse(i)}renderGroupProxy(){let e={name:"PROXY",type:"select",proxies:[],icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png"};return y.parse(e)}}function l(e){return!e.emby&&!e.info&&e.type!=="hysteria2"}var _={name:"Info",type:"url-test",emoji:"\u2139\uFE0F",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png",filter(e){return e.info}},I={name:"Auto",type:"url-test",emoji:"\uD83D\uDE80",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Auto.png",filter(e){return l(e)&&e.multiplier<=2}},se=new Set(["CA","CN","CU","HK","IR","KP","MO","NL","TW","US"]),X={name:"Binance",type:"url-test",emoji:"\uD83E\uDE99",url:"https://api.binance.com/api/v3/ping",filter(e){return l(e)&&!!e.country&&!se.has(e.country.cca2)}},pe=new Set(["HK","MO"]),j={name:"AI",type:"url-test",emoji:"\uD83E\uDD16",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/AI.png",filter(e){return l(e)&&!!e.country&&!pe.has(e.country.cca2)}},H={name:"Download",type:"url-test",emoji:"\uD83D\uDCE5",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Download.png",filter(e){return l(e)&&e.multiplier<=1}},L={name:"Stream",type:"url-test",emoji:"\uD83D\uDCFA",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/YouTube.png",filter(e){return l(e)&&e.multiplier<2}};var G={name:"CitrusLab Emby",type:"url-test",emoji:"\uD83C\uDF5F",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Emby.png",url:"https://shenmi.link",filter(e){return e.provider.name==="CitrusLab"&&e.emby}};import me from"world-countries";import P from"@twemoji/api";function k(e){let{cca2:o,flag:r}=e,t=P.convert.toCodePoint(r),i="".concat(P.base,P.size,"/",t,P.ext);return{name:e.name.common,type:o===p.cca2?"select":"url-test",emoji:r,icon:i,filter(m){return l(m)&&m.country.cca2===o}}}function N(){return[I,_,j,X,G,H,L,...me.map(k),k(p)]}class n{async inferBulk(e){return await Promise.all(e.map((o)=>this.infer(o)))}}import U from"consola";import he from"world-countries";import Q from"dns/promises";import fe from"dataloader";import W from"zod";import ne from"dataloader";import ae from"ky";import*as J from"remeda";import c from"zod";var le=c.looseObject({ip:c.union([c.ipv4(),c.ipv6()]),location:c.looseObject({country_code:c.string().length(2)}).optional()}),ce=c.record(c.string(),le);class z{endpoints="https://api.ipapi.is/";loader;key;constructor(){this.loader=new ne(async(e)=>await this.batchLoadFn(e),{maxBatchSize:100}),this.key=process.env.IPAPI_IS_KEY}async lookup(e){return await this.loader.load(e)}async batchLoadFn(e){let o=await ae.post(this.endpoints,{json:{ips:e,key:this.key}}).json();o=J.omit(o,["total_elapsed_ms"]);let r=ce.parse(o);return e.map((t)=>r[t])}}class b{api;loader;constructor(){this.api=new z,this.loader=new fe(async(e)=>await this.batchLoadFn(e))}async lookup(e){return await this.loader.load(e)}async batchLoadFn(e){return await Promise.all(e.map(async(o)=>await this.loadFn(o)))}async loadFn(e){let o=[];if(de(e))o=[e];else o=(await Q.lookup(e,{all:!0})).map((i)=>i.address);let r=await Promise.all(o.map(async(t)=>await this.api.lookup(t)));for(let t of r){if(!t.location?.country_code)continue;return t}return{ip:o[0]||"",location:{country_code:"UN"}}}}function de(e){return W.ipv4().safeParse(e).success||W.ipv6().safeParse(e).success}class A extends n{geoip=new b;async infer(e){if(e.emby||e.info)return e.country=p,e;if(e.country.cca2===p.cca2)e=this.inferFromName(e);if(e.country.cca2===p.cca2)e=await this.inferFromServer(e);if(e.country.cca2===p.cca2)U.fail(`${e.prettyName} (${D(e.country)})`);return e}inferFromName(e){let o=e.name;for(let r of he){if(r.cca2==="CN")continue;for(let t of ye(r)){if(!t)continue;if(t.test(o))return U.success(`${e.prettyName} ~ ${t} (${D(r)})`),e.country=r,e}}return e}async inferFromServer(e){let o=await this.geoip.lookup(e.server);if(o.location?.country_code)e.country=w(o.location.country_code)||p;else e.country=p;if(e.country.cca2!==p.cca2)U.success(`${e.prettyName} -> ${o.ip} (${D(e.country)})`);return e}}function*ye(e){let o=new Set(["GB"]);function r(i){if(!i)return;if(o.has(i))return;return new RegExp(`\\b${i}\\b`)}function t(i){if(!i)return;if(o.has(i))return;return new RegExp(i,"iu")}for(let i of["en","zh"])for(let m of["narrow","short","long"]){let O=new Intl.DisplayNames(i,{style:m,type:"region"});if(m==="narrow"||m==="short")yield r(O.of(e.cca2));else if(m==="long")yield t(O.of(e.cca2))}yield t(e.name.common),yield t(e.name.official);for(let i in e.name.native)yield t(e.name.native[i].common),yield t(e.name.native[i].official);yield r(e.cca2),yield r(e.cca3),yield r(e.cioc);for(let i of e.capital)yield t(i);yield t(e.flag)}function D(e){return`${e.flag} ${e.name.common} (${e.cca2})`}import ue from"consola";class v extends n{pattern=/emby/i;async infer(e){if(e.emby=this.pattern.test(e.name),e.emby)ue.success(`${e.prettyName} ~ ${this.pattern}`);return e}}import Me from"consola";class R extends n{pattern=/Expire|Traffic|\u5269\u4F59|\u5957\u9910\u5230\u671F/iu;async infer(e){if(e.info=this.pattern.test(e.name),e.info)Me.success(`${e.prettyName} ~ ${this.pattern}`);return e}}class Z extends n{inferrers;constructor(e){super();if(!e)e=[new v,new R,new A];this.inferrers=e}async infer(e){for(let o of this.inferrers)e=await o.infer(e);return e}async inferBulk(e){return await Promise.all(e.map((o)=>this.infer(o)))}}import Pe from"fs/promises";import ze from"yaml";import xe from"consola";import ge from"ky";import{z as a}from"zod";var C=a.object({name:a.string(),free:a.boolean().default(!1),jms:a.object({url:a.url()}).optional(),mihomo:a.object({url:a.url()}).optional()}),T=a.object({providers:a.array(C)});import mr from"ky";var Oe=process.env.SUBCONVERTER_URL||"https://url.v1.mk/sub";function q(e,o){let r=new URL(Oe);return r.searchParams.set("url",e),r.searchParams.set("target",o),r.searchParams.set("list","true"),r}class S{name;jms;mihomo;constructor(e){let{name:o,jms:r,mihomo:t}=C.parse(e);this.name=o,this.jms=r,this.mihomo=t}async fetchOutboundsMihomo(){let e=this.getMihomoURL();if(!e)return[];let o=new Headers({"User-Agent":"clash.meta"}),r=await ge.get(e,{headers:o}).text();return f(r).proxies.map((i)=>new u(i,this))}warnFormat(e){xe.warn(`Provider '${this.name}' does not support '${e}'`)}getMihomoURL(){if(this.mihomo)return this.mihomo.url;if(this.jms)return q(this.jms.url,"clash");this.warnFormat("mihomo");return}}class M{providers;static async load(e){let o=await Pe.readFile(e,"utf8"),r=ze.parse(o),t=T.parse(r);return new M(t.providers)}constructor(e){this.providers=e.map((o)=>new S(o))}async fetchMihomoOutbounds(){return(await Promise.all(this.providers.map((o)=>o.fetchOutboundsMihomo()))).flat()}}var $=Ae({docs:{brief:""},async func(e){ve.level=6;let o=N(),r=await M.load(e.profile),t=await d.load(e.template),i=await r.fetchMihomoOutbounds();i=await new Z().inferBulk(i);let O=t.render(i,o);await be.writeFile(e.output,O)},parameters:{flags:{output:{kind:"parsed",brief:"",parse:String,default:"mihomo.yaml"},profile:{kind:"parsed",brief:"",parse:String,default:"profile.yaml"},template:{kind:"parsed",brief:"",parse:String,default:"templates/mihomo/default.yaml"}}}});var ee=Ze({routes:{mihomo:$},docs:{brief:V}}),B=Re(ee,{name:"sub-store",versionInfo:{currentVersion:K}});import Ce from"fs";import Se from"os";import we from"path";var F={process,os:Se,fs:Ce,path:we};Ee(B,process.argv.slice(2),F);
3
+ import{run as Co}from"@stricli/core";import{buildApplication as Ao,buildRouteMap as Io}from"@stricli/core";var B="0.1.11",T="";import bo from"fs/promises";import{buildCommand as zo}from"@stricli/core";import Ro from"consola";import q from"world-countries";var m={name:{common:"Unknown"},cca2:"UN",flag:"\uD83C\uDDFA\uD83C\uDDF3"};function v(o){return q.find((e)=>e.cca2===o)}import $ from"dns/promises";import to from"dataloader";import V from"zod";import W from"dataloader";import oo from"ky";import*as Y from"remeda";import a from"zod";var eo=a.looseObject({ip:a.union([a.ipv4(),a.ipv6()]),location:a.looseObject({country_code:a.string().length(2)}).optional()}),ro=a.record(a.string(),eo);class y{endpoints="https://api.ipapi.is/";loader;key;constructor(){this.loader=new W(async(o)=>await this.batchLoadFn(o),{maxBatchSize:100}),this.key=process.env.IPAPI_IS_KEY}async lookup(o){return await this.loader.load(o)}async batchLoadFn(o){let e=await oo.post(this.endpoints,{json:{ips:o,key:this.key}}).json();e=Y.omit(e,["total_elapsed_ms"]);let r=ro.parse(e);return o.map((t)=>r[t])}}class O{api;loader;constructor(){this.api=new y,this.loader=new to(async(o)=>await this.batchLoadFn(o))}async lookup(o){return await this.loader.load(o)}async batchLoadFn(o){return await Promise.all(o.map(async(e)=>await this.loadFn(e)))}async loadFn(o){let e=[];if(io(o))e=[o];else e=(await $.lookup(o,{all:!0})).map((i)=>i.address);let r=await Promise.all(e.map(async(t)=>await this.api.lookup(t)));for(let t of r){if(!t.location?.country_code)continue;return t}return{ip:e[0]||"",location:{country_code:"UN"}}}}function io(o){return V.ipv4().safeParse(o).success||V.ipv6().safeParse(o).success}var so=process.env.SUBLINK_URL||"https://sublink.liblaf.me/clash";function C(o){let e=new URL(so);return e.searchParams.set("config",o),e.searchParams.set("ua","clash.meta"),e}class P{provider;country=m;info=!1;emby=!1;multiplier=1;constructor(o){this.provider=o}get prettyName(){let o=this.name;if(this.provider.name==="JMS"){let e=this.name.match(/@(?<name>[\w-]+)/);if(e)o=e.groups?.name??this.name}if(o.startsWith("\u3010"))return`[${this.provider.name}]${o}`;return`[${this.provider.name}] ${o}`}}import po from"consola";import mo from"ky";import{z as c}from"zod";var J=c.object({name:c.string(),free:c.boolean().default(!1),jms:c.object({url:c.url()}).optional(),mihomo:c.object({url:c.url()}).optional()});class b{name;jms;mihomo;constructor(o){let{name:e,jms:r,mihomo:t}=J.parse(o);this.name=e,this.jms=r,this.mihomo=t}async fetchOutboundsMihomo(){let o=this.getMihomoURL();if(!o)return[];let e=new Headers({"User-Agent":"clash.meta"}),r=await mo.get(o,{headers:e}).text();return d(r).proxies.map((i)=>new M(i,this))}warnFormat(o){po.warn(`Provider '${this.name}' does not support '${o}'`)}getMihomoURL(){if(this.mihomo)return this.mihomo.url;if(this.jms)return C(this.jms.url);this.warnFormat("mihomo");return}}import s from"zod";var x=s.looseObject({name:s.string(),type:s.string(),server:s.string()}),g=s.looseObject({name:s.string(),type:s.enum(["select","url-test"]),proxies:s.array(s.string()),url:s.url().default("https://cp.cloudflare.com"),lazy:s.boolean().default(!0),"expected-status":s.int().min(100).max(599).default(204),icon:s.url().optional()}),z=s.looseObject({proxies:s.array(x).optional(),"proxy-groups":s.array(g).optional(),rules:s.array(s.string()).optional()});class M extends P{raw;constructor(o,e){super(e);this.raw=x.parse(o)}get name(){return this.raw.name}get type(){return this.raw.type}get server(){return this.raw.server}get mihomo(){return{...this.raw,name:this.prettyName}}}import no from"yaml";function d(o){let e=no.parse(o,{merge:!0});return z.parse(e)}import ao from"fs/promises";import*as R from"remeda";import lo from"yaml";class h{template;static async load(o){let e=await ao.readFile(o,"utf8");return new h(e)}constructor(o){this.template=d(o)}render(o,e){let r=R.clone(this.template);r.proxies=o.map((i)=>i.mihomo);let t=this.renderGroupProxy();r["proxy-groups"]=[t];for(let i of e){let p=this.renderGroup(o,i);if(!p)continue;r["proxy-groups"].push(p),t.proxies.push(p.name)}return r=this.sanitize(r),lo.stringify(r,{aliasDuplicateObjects:!1,sortMapEntries:!0})}sanitize(o){o=R.omitBy(o,(r,t)=>t.startsWith("__"));let e=new Set(["DIRECT","REJECT","REJECT-DROP","PASS"]);for(let r of o.proxies||[])e.add(r.name);for(let r of o["proxy-groups"]||[])e.add(r.name);if(o.rules)o.rules=o.rules.filter((r)=>{let t=r.split(",").filter((p)=>p.trim()!=="no-resolve"),i=t[t.length-1].trim();return e.has(i)});return o}renderGroup(o,e){let r=o.filter(e.filter);if(r.length===0)return;let t=r.map((p)=>p.prettyName),i={name:e.name,type:e.type,proxies:t,url:e.url,icon:e.icon};return g.parse(i)}renderGroupProxy(){let o={name:"PROXY",type:"select",proxies:[],icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png"};return g.parse(o)}}function f(o){return!o.emby&&!o.info&&o.type!=="hysteria2"}var E={name:"Info",type:"url-test",emoji:"\u2139\uFE0F",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png",filter(o){return o.info}},w={name:"Auto",type:"url-test",emoji:"\uD83D\uDE80",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Auto.png",filter(o){return f(o)&&o.multiplier<=2}},co=new Set(["CA","CN","CU","HK","IR","KP","MO","NL","TW","US"]),K={name:"Binance",type:"url-test",emoji:"\uD83E\uDE99",url:"https://api.binance.com/api/v3/ping",filter(o){return f(o)&&!!o.country&&!co.has(o.country.cca2)}},fo=new Set(["HK","MO"]),G={name:"AI",type:"url-test",emoji:"\uD83E\uDD16",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/AI.png",filter(o){return f(o)&&!!o.country&&!fo.has(o.country.cca2)}};var _={name:"Stream",type:"url-test",emoji:"\uD83D\uDCFA",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/YouTube.png",filter(o){return f(o)&&o.multiplier<2}};import ho from"world-countries";import A from"@twemoji/api";function j(o,e){let{cca2:r,flag:t}=o,i=A.convert.toCodePoint(t),p="".concat(A.base,A.size,"/",i,A.ext);return{name:o.name.common,type:e?.type??"url-test",emoji:t,icon:p,filter(l){return f(l)&&l.country.cca2===r}}}function H(){return[w,E,G,K,_,...ho.map((o)=>j(o)),j(m)]}class u{async process(o){return await Promise.all(o.map(async(e)=>await this.processOne(e)))}}import L from"consola";import uo from"world-countries";class I extends u{geoip=new O;async processOne(o){if(o.emby||o.info)return o.country=m,o;if(o.country.cca2===m.cca2)o=this.inferFromName(o);if(o.country.cca2===m.cca2)o=await this.inferFromServer(o);if(o.country.cca2===m.cca2)L.fail(`${o.prettyName} (${k(o.country)})`);return o}inferFromName(o){let e=o.name;for(let r of uo){if(r.cca2==="CN")continue;for(let t of yo(r)){if(!t)continue;if(t.test(e))return L.success(`${o.prettyName} ~ ${t} (${k(r)})`),o.country=r,o}}return o}async inferFromServer(o){let e=await this.geoip.lookup(o.server);if(e.location?.country_code)o.country=v(e.location.country_code)||m;else o.country=m;if(o.country.cca2!==m.cca2)L.success(`${o.prettyName} -> ${e.ip} (${k(o.country)})`);return o}}function*yo(o){let e=new Set(["GB"]);function r(i){if(!i)return;if(e.has(i))return;return new RegExp(`\\b${i}\\b`)}function t(i){if(!i)return;if(e.has(i))return;return new RegExp(i,"iu")}for(let i of["en","zh"])for(let p of["narrow","short","long"]){let l=new Intl.DisplayNames(i,{style:p,type:"region"});if(p==="narrow"||p==="short")yield r(l.of(o.cca2));else if(p==="long")yield t(l.of(o.cca2))}yield t(o.name.common),yield t(o.name.official);for(let i in o.name.native)yield t(o.name.native[i].common),yield t(o.name.native[i].official);yield r(o.cca2),yield r(o.cca3),yield r(o.cioc);for(let i of o.capital)yield t(i);yield t(o.flag)}function k(o){return`${o.flag} ${o.name.common} (${o.cca2})`}import Oo from"consola";class Z extends u{pattern=/Expire|Traffic|\u5269\u4F59|\u5957\u9910\u5230\u671F/iu;async processOne(o){if(o.info=this.pattern.test(o.name),o.info)Oo.success(`${o.prettyName} ~ ${this.pattern}`);return o}}import Mo from"fs/promises";import xo from"yaml";import{z as n}from"zod";var go=n.object({name:n.string(),free:n.boolean().default(!1),jms:n.object({url:n.url()}).optional(),mihomo:n.object({url:n.url()}).optional()}),Po=n.object({providers:n.array(go)});class S{providers;static async load(o){let e=await Mo.readFile(o,"utf8"),r=xo.parse(e),t=Po.parse(r);return new S(t.providers)}constructor(o){this.providers=o.map((e)=>new b(e))}async fetchMihomoOutbounds(){return(await Promise.all(this.providers.map(async(e)=>await e.fetchOutboundsMihomo()))).flat()}}var D=zo({docs:{brief:""},async func(o){Ro.level=6;let e=H(),r=await S.load(o.profile),t=await h.load(o.template),i=await r.fetchMihomoOutbounds(),p=[new I,new Z];for(let Q of p)i=await Q.process(i);let l=t.render(i,e);await bo.writeFile(o.output,l)},parameters:{flags:{output:{kind:"parsed",brief:"",parse:String,default:"mihomo.yaml"},profile:{kind:"parsed",brief:"",parse:String,default:"profile.yaml"},template:{kind:"parsed",brief:"",parse:String,default:"templates/mihomo/default.yaml"}}}});var X=Io({routes:{mihomo:D},docs:{brief:T}}),U=Ao(X,{name:"sub-store",scanner:{caseStyle:"allow-kebab-for-camel"},versionInfo:{currentVersion:B}});import Zo from"fs";import So from"os";import vo from"path";var N={process,os:So,fs:Zo,path:vo};Co(U,process.argv.slice(2),N);
4
4
 
5
- //# debugId=D8736C8FA46E4ED164756E2164756E21
5
+ //# debugId=F0D751FFD124BACE64756E2164756E21
6
6
  //# sourceMappingURL=sub-store.js.map
@@ -1,34 +1,30 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["src/bin/sub-store.ts", "src/cli/app.ts", "src/cli/mihomo.ts", "src/utils/countries.ts", "src/outbound.ts", "src/formats/mihomo/schema.ts", "src/formats/mihomo/outbound.ts", "src/formats/mihomo/parse.ts", "src/formats/mihomo/template.ts", "src/group/common.ts", "src/group/extra.ts", "src/group/factory.ts", "src/group/country.ts", "src/infer/abc.ts", "src/infer/country.ts", "src/geoip/geoip.ts", "src/geoip/ipapi.is.ts", "src/infer/emby.ts", "src/infer/info.ts", "src/infer/container.ts", "src/provider/profile.ts", "src/provider/provider.ts", "src/provider/schema.ts", "src/provider/subconvert.ts", "src/cli/context.ts"],
3
+ "sources": ["src/bin/sub-store.ts", "src/cli/app.ts", "src/cli/mihomo.ts", "src/utils/countries.ts", "src/utils/geoip/geoip.ts", "src/utils/geoip/ipapi.is.ts", "src/utils/sublink.ts", "src/core/outbound.ts", "src/core/provider.ts", "src/formats/mihomo/schema.ts", "src/formats/mihomo/outbound.ts", "src/formats/mihomo/parse.ts", "src/formats/mihomo/template.ts", "src/group/common.ts", "src/group/factory.ts", "src/group/country.ts", "src/processor/base.ts", "src/processor/country.ts", "src/processor/info.ts", "src/profile.ts", "src/cli/context.ts"],
4
4
  "sourcesContent": [
5
5
  "#!/usr/bin/env bun\nimport { run } from \"@stricli/core\";\nimport { app, context } from \"../cli\";\n\nrun(app, process.argv.slice(2), context);\n",
6
- "import type { Application, RouteMap } from \"@stricli/core\";\nimport { buildApplication, buildRouteMap } from \"@stricli/core\";\nimport { description, version } from \"../../package.json\";\nimport type { Context } from \"./context\";\nimport { mihomo } from \"./mihomo\";\n\nexport const routes: RouteMap<Context> = buildRouteMap({\n routes: { mihomo },\n docs: { brief: description },\n});\n\nexport const app: Application<Context> = buildApplication(routes, {\n name: \"sub-store\",\n versionInfo: { currentVersion: version },\n});\n",
7
- "import fs from \"node:fs/promises\";\nimport { buildCommand, type Command } from \"@stricli/core\";\nimport consola from \"consola\";\nimport { type MihomoOutbound, MihomoTemplate } from \"../formats\";\nimport { type Group, newGroups } from \"../group\";\nimport { InferrerContainer } from \"../infer\";\nimport { Profile } from \"../provider\";\nimport type { Context } from \"./context\";\n\ntype Flags = {\n output: string;\n profile: string;\n template: string;\n};\n\nexport const mihomo: Command<Context> = buildCommand({\n docs: { brief: \"\" },\n async func(this: Context, flags: Flags): Promise<void> {\n consola.level = 6;\n const groups: Group[] = newGroups();\n const profile = await Profile.load(flags.profile);\n const template: MihomoTemplate = await MihomoTemplate.load(flags.template);\n let outbounds: MihomoOutbound[] = await profile.fetchMihomoOutbounds();\n const inferrer = new InferrerContainer();\n outbounds = await inferrer.inferBulk(outbounds);\n const config: string = template.render(outbounds, groups);\n await fs.writeFile(flags.output, config);\n },\n parameters: {\n flags: {\n output: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"mihomo.yaml\",\n },\n profile: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"profile.yaml\",\n },\n template: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"templates/mihomo/default.yaml\",\n },\n },\n },\n});\n",
6
+ "import type { Application, RouteMap } from \"@stricli/core\";\nimport { buildApplication, buildRouteMap } from \"@stricli/core\";\nimport { description, version } from \"../../package.json\";\nimport type { Context } from \"./context\";\nimport { mihomo } from \"./mihomo\";\n\nexport const routes: RouteMap<Context> = buildRouteMap({\n routes: { mihomo },\n docs: { brief: description },\n});\n\nexport const app: Application<Context> = buildApplication(routes, {\n name: \"sub-store\",\n scanner: { caseStyle: \"allow-kebab-for-camel\" },\n versionInfo: { currentVersion: version },\n});\n",
7
+ "import fs from \"node:fs/promises\";\nimport { buildCommand, type Command } from \"@stricli/core\";\nimport consola from \"consola\";\nimport type { MihomoOutbound } from \"../formats\";\nimport { MihomoTemplate } from \"../formats\";\nimport type { Group } from \"../group\";\nimport { defaultGroups } from \"../group\";\nimport type { Processor } from \"../processor\";\nimport { ProcessorCountry, ProcessorInfo } from \"../processor\";\nimport { Profile } from \"../profile\";\nimport type { Context } from \"./context\";\n\ntype Flags = {\n output: string;\n profile: string;\n template: string;\n};\n\nexport const mihomo: Command<Context> = buildCommand({\n docs: { brief: \"\" },\n async func(this: Context, flags: Flags): Promise<void> {\n consola.level = 6;\n const groups: Group[] = defaultGroups();\n const profile = await Profile.load(flags.profile);\n const template: MihomoTemplate = await MihomoTemplate.load(flags.template);\n let outbounds: MihomoOutbound[] = await profile.fetchMihomoOutbounds();\n const processors: Processor[] = [\n new ProcessorCountry(),\n new ProcessorInfo(),\n ];\n for (const processor of processors)\n outbounds = await processor.process(outbounds);\n const config: string = template.render(outbounds, groups);\n await fs.writeFile(flags.output, config);\n },\n parameters: {\n flags: {\n output: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"mihomo.yaml\",\n },\n profile: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"profile.yaml\",\n },\n template: {\n kind: \"parsed\",\n brief: \"\",\n parse: String,\n default: \"templates/mihomo/default.yaml\",\n },\n },\n },\n});\n",
8
8
  "import type { Country } from \"world-countries\";\nimport countries from \"world-countries\";\n\nexport const COUNTRY_UNKNOWN = {\n name: { common: \"Unknown\" },\n cca2: \"UN\",\n flag: \"πŸ‡ΊπŸ‡³\",\n} as Country;\n\nexport function lookupCountry(cca2: string): Country | undefined {\n return countries.find((country: Country): boolean => country.cca2 === cca2);\n}\n",
9
- "import type { Country } from \"world-countries\";\nimport type { Provider } from \"./provider\";\nimport { COUNTRY_UNKNOWN } from \"./utils\";\n\nexport abstract class Outbound {\n public readonly provider: Provider;\n\n // inference\n public connection: boolean = false;\n public country: Country = COUNTRY_UNKNOWN;\n public emby: boolean = false;\n public info: boolean = false;\n public multiplier: number = 1.0;\n\n constructor(provider: Provider) {\n this.provider = provider;\n }\n\n abstract get name(): string;\n\n abstract get type(): string;\n\n abstract get server(): string;\n\n get prettyName(): string {\n let name: string = this.name;\n if (this.provider.name === \"JMS\") {\n const match = this.name.match(/@(?<name>[\\w-]+)/);\n if (match) name = match.groups?.name ?? this.name;\n }\n if (name.startsWith(\"【\")) return `[${this.provider.name}]${name}`;\n return `[${this.provider.name}] ${name}`;\n }\n}\n",
10
- "import z from \"zod\";\n\nexport const MIHOMO_NODE_SCHEMA: z.ZodObject<\n {\n name: z.ZodString;\n type: z.ZodString;\n server: z.ZodString;\n },\n z.core.$loose\n> = z.looseObject({\n name: z.string(),\n type: z.string(),\n server: z.string(),\n});\nexport type MihomoNode = z.infer<typeof MIHOMO_NODE_SCHEMA>;\nexport type MihomoNodeOptions = z.input<typeof MIHOMO_NODE_SCHEMA>;\n\nexport const MIHOMO_PROXY_GROUP_SCHEMA: z.ZodObject<\n {\n name: z.ZodString;\n type: z.ZodEnum<{\n select: \"select\";\n \"url-test\": \"url-test\";\n }>;\n proxies: z.ZodArray<z.ZodString>;\n url: z.ZodDefault<z.ZodURL>;\n lazy: z.ZodDefault<z.ZodBoolean>;\n \"expected-status\": z.ZodDefault<z.ZodInt>;\n icon: z.ZodOptional<z.ZodURL>;\n },\n z.core.$loose\n> = z.looseObject({\n name: z.string(),\n type: z.enum([\"select\", \"url-test\"]),\n proxies: z.array(z.string()),\n url: z.url().default(\"https://cp.cloudflare.com\"),\n lazy: z.boolean().default(true),\n \"expected-status\": z.int().min(100).max(599).default(204),\n icon: z.url().optional(),\n});\nexport type MihomoProxyGroup = z.infer<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\nexport type MihomoProxyGroupOptions = z.input<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\n\nexport const MIHOMO_SCHEMA: z.ZodObject<\n {\n proxies: z.ZodOptional<\n z.ZodArray<\n z.ZodObject<\n {\n name: z.ZodString;\n type: z.ZodString;\n server: z.ZodString;\n },\n z.core.$loose\n >\n >\n >;\n \"proxy-groups\": z.ZodOptional<\n z.ZodArray<\n z.ZodObject<\n {\n name: z.ZodString;\n type: z.ZodEnum<{\n select: \"select\";\n \"url-test\": \"url-test\";\n }>;\n proxies: z.ZodArray<z.ZodString>;\n url: z.ZodDefault<z.ZodURL>;\n lazy: z.ZodDefault<z.ZodBoolean>;\n \"expected-status\": z.ZodDefault<z.ZodInt>;\n icon: z.ZodOptional<z.ZodURL>;\n },\n z.core.$loose\n >\n >\n >;\n },\n z.core.$loose\n> = z.looseObject({\n proxies: z.array(MIHOMO_NODE_SCHEMA).optional(),\n \"proxy-groups\": z.array(MIHOMO_PROXY_GROUP_SCHEMA).optional(),\n});\nexport type Mihomo = z.infer<typeof MIHOMO_SCHEMA>;\n",
11
- "import { Outbound } from \"../../outbound\";\nimport type { Provider } from \"../../provider\";\nimport type { MihomoNode, MihomoNodeOptions } from \"./schema\";\nimport { MIHOMO_NODE_SCHEMA } from \"./schema\";\n\nexport class MihomoOutbound extends Outbound {\n private readonly raw: MihomoNode;\n\n public constructor(raw: MihomoNodeOptions, provider: Provider) {\n super(provider);\n this.raw = MIHOMO_NODE_SCHEMA.parse(raw);\n }\n\n public override get name(): string {\n return this.raw.name;\n }\n\n public override get type(): string {\n return this.raw.type;\n }\n\n public override get server(): string {\n return this.raw.server;\n }\n\n public get mihomo(): MihomoNode {\n return { ...this.raw, name: this.prettyName };\n }\n}\n",
9
+ "import type { LookupAddress } from \"node:dns\";\nimport dns from \"node:dns/promises\";\nimport DataLoader from \"dataloader\";\nimport z from \"zod\";\nimport { type GeoIpApiResponse, IpapiIs } from \"./ipapi.is\";\n\nexport class GeoIP {\n private api: IpapiIs;\n private loader: DataLoader<string, GeoIpApiResponse>;\n\n public constructor() {\n this.api = new IpapiIs();\n this.loader = new DataLoader(\n async (servers: readonly string[]): Promise<GeoIpApiResponse[]> =>\n await this.batchLoadFn(servers),\n );\n }\n\n public async lookup(server: string): Promise<GeoIpApiResponse> {\n return await this.loader.load(server);\n }\n\n protected async batchLoadFn(\n servers: readonly string[],\n ): Promise<GeoIpApiResponse[]> {\n return await Promise.all(\n servers.map(\n async (server: string): Promise<GeoIpApiResponse> =>\n await this.loadFn(server),\n ),\n );\n }\n\n protected async loadFn(server: string): Promise<GeoIpApiResponse> {\n let ips: string[] = [];\n if (isIpAddr(server)) {\n ips = [server];\n } else {\n const addresses: LookupAddress[] = await dns.lookup(server, {\n all: true,\n });\n ips = addresses.map((addr: LookupAddress): string => addr.address);\n }\n const responses: GeoIpApiResponse[] = await Promise.all(\n ips.map(\n async (ip: string): Promise<GeoIpApiResponse> =>\n await this.api.lookup(ip),\n ),\n );\n for (const response of responses) {\n if (!response.location?.country_code) continue;\n return response;\n }\n return { ip: ips[0] || \"\", location: { country_code: \"UN\" } };\n }\n}\n\nfunction isIpAddr(data: string): boolean {\n return z.ipv4().safeParse(data).success || z.ipv6().safeParse(data).success;\n}\n",
10
+ "import DataLoader from \"dataloader\";\nimport ky from \"ky\";\nimport * as R from \"remeda\";\nimport z from \"zod\";\n\nconst RESPONSE_SCHEMA: z.ZodObject<{\n ip: z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6]>;\n location: z.ZodOptional<z.ZodObject<{ country_code: z.ZodString }>>;\n}> = z.looseObject({\n ip: z.union([z.ipv4(), z.ipv6()]),\n location: z.looseObject({ country_code: z.string().length(2) }).optional(),\n});\nexport type GeoIpApiResponse = z.infer<typeof RESPONSE_SCHEMA>;\n\nconst BULK_RESPONSE_SCHEMA: z.ZodRecord<z.ZodString, typeof RESPONSE_SCHEMA> =\n z.record(z.string(), RESPONSE_SCHEMA);\ntype BulkApiResponse = z.infer<typeof BULK_RESPONSE_SCHEMA>;\n\nexport class IpapiIs {\n public readonly endpoints: string = \"https://api.ipapi.is/\";\n private loader: DataLoader<string, GeoIpApiResponse>;\n private readonly key?: string;\n\n public constructor() {\n this.loader = new DataLoader(\n async (ips: readonly string[]): Promise<GeoIpApiResponse[]> =>\n await this.batchLoadFn(ips),\n { maxBatchSize: 100 },\n );\n this.key = process.env.IPAPI_IS_KEY;\n }\n\n public async lookup(ip: string): Promise<GeoIpApiResponse> {\n return await this.loader.load(ip);\n }\n\n protected async batchLoadFn(\n ips: readonly string[],\n ): Promise<GeoIpApiResponse[]> {\n let data: any = await ky\n .post(this.endpoints, { json: { ips, key: this.key } })\n .json();\n data = R.omit(data, [\"total_elapsed_ms\"]);\n const response: BulkApiResponse = BULK_RESPONSE_SCHEMA.parse(data);\n return ips.map((ip: string): GeoIpApiResponse => response[ip]!);\n }\n}\n",
11
+ "const SUBLINK_URL: string =\n process.env.SUBLINK_URL || \"https://sublink.liblaf.me/clash\";\n\nexport function sublinkClashUrl(url: string): URL {\n const req = new URL(SUBLINK_URL);\n req.searchParams.set(\"config\", url);\n req.searchParams.set(\"ua\", \"clash.meta\");\n return req;\n}\n",
12
+ "import type { Country } from \"world-countries\";\nimport { COUNTRY_UNKNOWN } from \"../utils\";\nimport type { Provider } from \"./provider\";\n\nexport abstract class Outbound {\n public readonly provider: Provider;\n\n // metadata\n public country: Country = COUNTRY_UNKNOWN;\n public info: boolean = false;\n public emby: boolean = false;\n public multiplier: number = 1.0;\n [key: string]: any;\n\n constructor(provider: Provider) {\n this.provider = provider;\n }\n\n abstract get name(): string;\n\n abstract get type(): string;\n\n abstract get server(): string;\n\n get prettyName(): string {\n let name: string = this.name;\n if (this.provider.name === \"JMS\") {\n const match: RegExpMatchArray | null =\n this.name.match(/@(?<name>[\\w-]+)/);\n if (match) name = match.groups?.name ?? this.name;\n }\n if (name.startsWith(\"【\")) return `[${this.provider.name}]${name}`;\n return `[${this.provider.name}] ${name}`;\n }\n}\n",
13
+ "import consola from \"consola\";\nimport ky from \"ky\";\nimport { z } from \"zod\";\nimport type { Mihomo, MihomoNode } from \"../formats\";\nimport { MihomoOutbound, mihomoParse } from \"../formats\";\nimport { sublinkClashUrl } from \"../utils\";\n\nexport const PROVIDER_SCHEMA: z.ZodObject<{\n name: z.ZodString;\n free: z.ZodDefault<z.ZodBoolean>;\n jms: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }>>;\n mihomo: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }>>;\n}> = z.object({\n name: z.string(),\n free: z.boolean().default(false),\n jms: z.object({ url: z.url() }).optional(),\n mihomo: z.object({ url: z.url() }).optional(),\n});\nexport type ProviderOptions = z.input<typeof PROVIDER_SCHEMA>;\n\nexport class Provider {\n public readonly name: string;\n public readonly jms?: { url: string };\n public readonly mihomo?: { url: string };\n\n public constructor(options: ProviderOptions) {\n const { name, jms, mihomo } = PROVIDER_SCHEMA.parse(options);\n this.name = name;\n this.jms = jms;\n this.mihomo = mihomo;\n }\n\n public async fetchOutboundsMihomo(): Promise<MihomoOutbound[]> {\n const url: string | URL | undefined = this.getMihomoURL();\n if (!url) return [];\n const headers = new Headers({ \"User-Agent\": \"clash.meta\" });\n const text: string = await ky.get(url, { headers }).text();\n const config: Mihomo = mihomoParse(text);\n return config.proxies!.map(\n (proxy: MihomoNode): MihomoOutbound => new MihomoOutbound(proxy, this),\n );\n }\n\n protected warnFormat(format: string): void {\n consola.warn(`Provider '${this.name}' does not support '${format}'`);\n }\n\n protected getMihomoURL(): string | URL | undefined {\n if (this.mihomo) return this.mihomo.url;\n if (this.jms) return sublinkClashUrl(this.jms.url);\n this.warnFormat(\"mihomo\");\n return undefined;\n }\n}\n",
14
+ "import z from \"zod\";\n\nexport const MIHOMO_NODE_SCHEMA: z.ZodObject<{\n name: z.ZodString;\n type: z.ZodString;\n server: z.ZodString;\n}> = z.looseObject({\n name: z.string(),\n type: z.string(),\n server: z.string(),\n});\nexport type MihomoNode = z.infer<typeof MIHOMO_NODE_SCHEMA>;\nexport type MihomoNodeOptions = z.input<typeof MIHOMO_NODE_SCHEMA>;\n\nexport const MIHOMO_PROXY_GROUP_SCHEMA: z.ZodObject<{\n name: z.ZodString;\n type: z.ZodEnum<{\n select: \"select\";\n \"url-test\": \"url-test\";\n }>;\n proxies: z.ZodArray<z.ZodString>;\n url: z.ZodDefault<z.ZodURL>;\n lazy: z.ZodDefault<z.ZodBoolean>;\n \"expected-status\": z.ZodDefault<z.ZodInt>;\n icon: z.ZodOptional<z.ZodURL>;\n}> = z.looseObject({\n name: z.string(),\n type: z.enum([\"select\", \"url-test\"]),\n proxies: z.array(z.string()),\n url: z.url().default(\"https://cp.cloudflare.com\"),\n lazy: z.boolean().default(true),\n \"expected-status\": z.int().min(100).max(599).default(204),\n icon: z.url().optional(),\n});\nexport type MihomoProxyGroup = z.infer<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\nexport type MihomoProxyGroupOptions = z.input<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\n\nexport const MIHOMO_SCHEMA: z.ZodObject<{\n proxies: z.ZodOptional<\n z.ZodArray<\n z.ZodObject<{\n name: z.ZodString;\n type: z.ZodString;\n server: z.ZodString;\n }>\n >\n >;\n \"proxy-groups\": z.ZodOptional<\n z.ZodArray<\n z.ZodObject<{\n name: z.ZodString;\n type: z.ZodEnum<{\n select: \"select\";\n \"url-test\": \"url-test\";\n }>;\n proxies: z.ZodArray<z.ZodString>;\n url: z.ZodDefault<z.ZodURL>;\n lazy: z.ZodDefault<z.ZodBoolean>;\n \"expected-status\": z.ZodDefault<z.ZodInt>;\n icon: z.ZodOptional<z.ZodURL>;\n }>\n >\n >;\n rules: z.ZodOptional<z.ZodArray<z.ZodString>>;\n}> = z.looseObject({\n proxies: z.array(MIHOMO_NODE_SCHEMA).optional(),\n \"proxy-groups\": z.array(MIHOMO_PROXY_GROUP_SCHEMA).optional(),\n rules: z.array(z.string()).optional(),\n});\nexport type Mihomo = z.infer<typeof MIHOMO_SCHEMA>;\n",
15
+ "import type { Provider } from \"../../core\";\nimport { Outbound } from \"../../core\";\nimport type { MihomoNode, MihomoNodeOptions } from \"./schema\";\nimport { MIHOMO_NODE_SCHEMA } from \"./schema\";\n\nexport class MihomoOutbound extends Outbound {\n private readonly raw: MihomoNode;\n\n public constructor(raw: MihomoNodeOptions, provider: Provider) {\n super(provider);\n this.raw = MIHOMO_NODE_SCHEMA.parse(raw);\n }\n\n public override get name(): string {\n return this.raw.name;\n }\n\n public override get type(): string {\n return this.raw.type;\n }\n\n public override get server(): string {\n return this.raw.server;\n }\n\n public get mihomo(): MihomoNode {\n return { ...this.raw, name: this.prettyName };\n }\n}\n",
12
16
  "import YAML from \"yaml\";\nimport { MIHOMO_SCHEMA, type Mihomo } from \"./schema\";\n\nexport function mihomoParse(text: string): Mihomo {\n const data: any = YAML.parse(text, { merge: true });\n return MIHOMO_SCHEMA.parse(data);\n}\n",
13
- "import fs from \"node:fs/promises\";\nimport * as R from \"remeda\";\nimport YAML from \"yaml\";\nimport type { Group } from \"../../group\";\nimport type { MihomoOutbound } from \"./outbound\";\nimport { mihomoParse } from \"./parse\";\nimport {\n MIHOMO_PROXY_GROUP_SCHEMA,\n type Mihomo,\n type MihomoNode,\n type MihomoProxyGroup,\n type MihomoProxyGroupOptions,\n} from \"./schema\";\n\nexport class MihomoTemplate {\n template: Mihomo;\n\n static async load(path: string): Promise<MihomoTemplate> {\n const template: string = await fs.readFile(path, \"utf8\");\n return new MihomoTemplate(template);\n }\n\n public constructor(template: string) {\n this.template = mihomoParse(template);\n }\n\n public render(outbounds: readonly MihomoOutbound[], groups: Group[]): string {\n let config: Mihomo = R.clone(this.template);\n config.proxies = outbounds.map((o: MihomoOutbound): MihomoNode => o.mihomo);\n const groupProxy: MihomoProxyGroup = this.renderGroupProxy();\n config[\"proxy-groups\"] = [groupProxy];\n for (const group of groups) {\n const rendered: MihomoProxyGroup | undefined = this.renderGroup(\n outbounds,\n group,\n );\n if (!rendered) continue;\n config[\"proxy-groups\"].push(rendered);\n groupProxy.proxies.push(rendered.name);\n }\n config = this.sanitize(config);\n return YAML.stringify(config, { aliasDuplicateObjects: false });\n }\n\n protected sanitize(config: Mihomo): Mihomo {\n config = R.omitBy(config, (_value, key: string): boolean =>\n key.startsWith(\"__\"),\n );\n return config;\n }\n\n protected renderGroup(\n outbounds: readonly MihomoOutbound[],\n group: Group,\n ): MihomoProxyGroup | undefined {\n const filtered: MihomoOutbound[] = outbounds.filter(group.filter);\n if (filtered.length === 0) return undefined;\n const filteredNames: string[] = filtered.map(\n (o: MihomoOutbound): string => o.prettyName,\n );\n const options: MihomoProxyGroupOptions = {\n name: group.name,\n type: group.type,\n proxies: filteredNames,\n url: group.url,\n icon: group.icon,\n };\n return MIHOMO_PROXY_GROUP_SCHEMA.parse(options);\n }\n\n protected renderGroupProxy(): MihomoProxyGroup {\n const options: MihomoProxyGroupOptions = {\n name: \"PROXY\",\n type: \"select\",\n proxies: [],\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png\",\n };\n return MIHOMO_PROXY_GROUP_SCHEMA.parse(options);\n }\n}\n",
14
- "import type { Outbound } from \"../outbound\";\nimport type { Group } from \"./abc\";\n\nexport function good(outbound: Outbound): boolean {\n // connection quality of Hysteria2 is poor\n return !outbound.emby && !outbound.info && outbound.type !== \"hysteria2\";\n}\n\nexport const PROXY: Group = {\n name: \"PROXY\",\n type: \"select\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png\",\n filter(_outbound: Outbound): boolean {\n return false;\n },\n};\n\nexport const INFO: Group = {\n name: \"Info\",\n type: \"url-test\",\n emoji: \"ℹ️\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png\",\n filter(outbound: Outbound): boolean {\n return outbound.info;\n },\n};\n\nexport const AUTO: Group = {\n name: \"Auto\",\n type: \"url-test\",\n emoji: \"πŸš€\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Auto.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier <= 2.0;\n },\n};\n\nconst BINANCE_EXCLUDE_REGIONS = new Set([\n \"CA\",\n \"CN\",\n \"CU\",\n \"HK\",\n \"IR\",\n \"KP\",\n \"MO\",\n \"NL\",\n \"TW\",\n \"US\",\n]);\nexport const BINANCE: Group = {\n name: \"Binance\",\n type: \"url-test\",\n emoji: \"πŸͺ™\",\n // TODO: add icon\n url: \"https://api.binance.com/api/v3/ping\",\n filter(outbound: Outbound): boolean {\n return (\n good(outbound) &&\n !!outbound.country &&\n !BINANCE_EXCLUDE_REGIONS.has(outbound.country.cca2)\n );\n },\n};\n\nconst AI_EXCLUDE_REGIONS = new Set([\"HK\", \"MO\"]);\nexport const AI: Group = {\n name: \"AI\",\n type: \"url-test\",\n emoji: \"πŸ€–\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/AI.png\",\n filter(outbound: Outbound): boolean {\n return (\n good(outbound) &&\n !!outbound.country &&\n !AI_EXCLUDE_REGIONS.has(outbound.country.cca2)\n );\n },\n};\n\nexport const DOWNLOAD: Group = {\n name: \"Download\",\n type: \"url-test\",\n emoji: \"πŸ“₯\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Download.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier <= 1.0;\n },\n};\n\nexport const STREAM: Group = {\n name: \"Stream\",\n type: \"url-test\",\n emoji: \"πŸ“Ί\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/YouTube.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier < 2.0;\n },\n};\n",
15
- "import type { Outbound } from \"../outbound\";\nimport type { Group } from \"./abc\";\n\nexport const CITRUSLAB_EMBY: Group = {\n name: \"CitrusLab Emby\",\n type: \"url-test\",\n emoji: \"🍟\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Emby.png\",\n url: \"https://shenmi.link\",\n filter(outbound: Outbound): boolean {\n return outbound.provider.name === \"CitrusLab\" && outbound.emby;\n },\n};\n",
16
- "import countries from \"world-countries\";\nimport { COUNTRY_UNKNOWN } from \"../utils\";\nimport type { Group } from \"./abc\";\nimport { AI, AUTO, BINANCE, DOWNLOAD, INFO, STREAM } from \"./common\";\nimport { newCountryGroup } from \"./country\";\nimport { CITRUSLAB_EMBY } from \"./extra\";\n\nexport function newGroups(): Group[] {\n return [\n AUTO,\n INFO,\n AI,\n BINANCE,\n CITRUSLAB_EMBY,\n DOWNLOAD,\n STREAM,\n ...countries.map(newCountryGroup),\n newCountryGroup(COUNTRY_UNKNOWN),\n ];\n}\n",
17
- "import twemoji from \"@twemoji/api\";\nimport type { Country } from \"world-countries\";\nimport type { Outbound } from \"../outbound\";\nimport { COUNTRY_UNKNOWN } from \"../utils\";\nimport type { Group } from \"./abc\";\nimport { good } from \"./common\";\n\nexport function newCountryGroup(country: Country): Group {\n const { cca2, flag } = country;\n const codePoint: string = twemoji.convert.toCodePoint(flag);\n const icon: string = \"\".concat(\n twemoji.base,\n twemoji.size,\n \"/\",\n codePoint,\n twemoji.ext,\n );\n return {\n name: country.name.common,\n type: cca2 === COUNTRY_UNKNOWN.cca2 ? \"select\" : \"url-test\",\n emoji: flag,\n icon,\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.country.cca2 === cca2;\n },\n };\n}\n",
18
- "import type { Outbound } from \"../outbound\";\n\nexport abstract class Inferrer {\n public abstract infer<T extends Outbound>(outbound: T): Promise<T>;\n\n public async inferBulk<T extends Outbound>(\n outbounds: readonly T[],\n ): Promise<T[]> {\n return await Promise.all(\n outbounds.map((outbound: T): Promise<T> => this.infer(outbound)),\n );\n }\n}\n",
19
- "import consola from \"consola\";\nimport countries, { type Country } from \"world-countries\";\nimport { type ApiResponse, GeoIP } from \"../geoip\";\nimport type { Outbound } from \"../outbound\";\nimport { COUNTRY_UNKNOWN, lookupCountry } from \"../utils\";\nimport { Inferrer } from \"./abc\";\n\nexport class InferrerCountry extends Inferrer {\n private readonly geoip: GeoIP = new GeoIP();\n\n public override async infer<T extends Outbound>(outbound: T): Promise<T> {\n if (outbound.emby || outbound.info) {\n outbound.country = COUNTRY_UNKNOWN;\n return outbound;\n }\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2)\n outbound = this.inferFromName(outbound);\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2)\n outbound = await this.inferFromServer(outbound);\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2) {\n consola.fail(\n `${outbound.prettyName} (${prettyCountry(outbound.country)})`,\n );\n }\n return outbound;\n }\n\n protected inferFromName<T extends Outbound>(outbound: T): T {\n const name: string = outbound.name;\n for (const country of countries) {\n if (country.cca2 === \"CN\") continue;\n for (const pattern of patterns(country)) {\n if (!pattern) continue;\n if (pattern.test(name)) {\n consola.success(\n `${outbound.prettyName} ~ ${pattern} (${prettyCountry(country)})`,\n );\n outbound.country = country;\n return outbound;\n }\n }\n }\n return outbound;\n }\n\n protected async inferFromServer<T extends Outbound>(outbound: T): Promise<T> {\n const response: ApiResponse = await this.geoip.lookup(outbound.server);\n if (response.location?.country_code) {\n outbound.country =\n lookupCountry(response.location.country_code) || COUNTRY_UNKNOWN;\n } else {\n outbound.country = COUNTRY_UNKNOWN;\n }\n if (outbound.country.cca2 !== COUNTRY_UNKNOWN.cca2) {\n consola.success(\n `${outbound.prettyName} -> ${response.ip} (${prettyCountry(outbound.country)})`,\n );\n }\n return outbound;\n }\n}\n\nfunction* patterns(country: Country): Generator<RegExp | undefined> {\n const EXCLUDE_PATTERNS = new Set([\n \"GB\", // gigabyte\n ]);\n\n function short(pattern?: string): RegExp | undefined {\n if (!pattern) return undefined;\n if (EXCLUDE_PATTERNS.has(pattern)) return undefined;\n return new RegExp(`\\\\b${pattern}\\\\b`);\n }\n\n function long(pattern?: string): RegExp | undefined {\n if (!pattern) return undefined;\n if (EXCLUDE_PATTERNS.has(pattern)) return undefined;\n return new RegExp(pattern, \"iu\");\n }\n\n for (const locale of [\"en\", \"zh\"]) {\n for (const style of [\"narrow\", \"short\", \"long\"]) {\n const display = new Intl.DisplayNames(locale, {\n style: style as Intl.RelativeTimeFormatStyle,\n type: \"region\",\n });\n if (style === \"narrow\" || style === \"short\") {\n yield short(display.of(country.cca2));\n } else if (style === \"long\") {\n yield long(display.of(country.cca2));\n }\n }\n }\n yield long(country.name.common);\n yield long(country.name.official);\n for (const lang in country.name.native) {\n yield long(country.name.native[lang]!.common);\n yield long(country.name.native[lang]!.official);\n }\n yield short(country.cca2);\n // yield long(country.ccn3);\n yield short(country.cca3);\n yield short(country.cioc);\n for (const capital of country.capital) yield long(capital);\n // for (const alt of country.altSpellings) yield long(alt);\n yield long(country.flag);\n}\n\nfunction prettyCountry(country: Country): string {\n return `${country.flag} ${country.name.common} (${country.cca2})`;\n}\n",
20
- "import type { LookupAddress } from \"node:dns\";\nimport dns from \"node:dns/promises\";\nimport DataLoader from \"dataloader\";\nimport z from \"zod\";\nimport { type ApiResponse, IpapiIs } from \"./ipapi.is\";\n\nexport class GeoIP {\n private api: IpapiIs;\n private loader: DataLoader<string, ApiResponse>;\n\n public constructor() {\n this.api = new IpapiIs();\n this.loader = new DataLoader(\n async (servers: readonly string[]): Promise<ApiResponse[]> =>\n await this.batchLoadFn(servers),\n );\n }\n\n public async lookup(server: string): Promise<ApiResponse> {\n return await this.loader.load(server);\n }\n\n protected async batchLoadFn(\n servers: readonly string[],\n ): Promise<ApiResponse[]> {\n return await Promise.all(\n servers.map(\n async (server: string): Promise<ApiResponse> =>\n await this.loadFn(server),\n ),\n );\n }\n\n protected async loadFn(server: string): Promise<ApiResponse> {\n let ips: string[] = [];\n if (isIpAddr(server)) {\n ips = [server];\n } else {\n const addresses: LookupAddress[] = await dns.lookup(server, {\n all: true,\n });\n ips = addresses.map((addr: LookupAddress): string => addr.address);\n }\n const responses: ApiResponse[] = await Promise.all(\n ips.map(\n async (ip: string): Promise<ApiResponse> => await this.api.lookup(ip),\n ),\n );\n for (const response of responses) {\n if (!response.location?.country_code) continue;\n return response;\n }\n return { ip: ips[0] || \"\", location: { country_code: \"UN\" } };\n }\n}\n\nfunction isIpAddr(data: string): boolean {\n return z.ipv4().safeParse(data).success || z.ipv6().safeParse(data).success;\n}\n",
21
- "import DataLoader from \"dataloader\";\nimport ky from \"ky\";\nimport * as R from \"remeda\";\nimport z from \"zod\";\n\nconst RESPONSE_SCHEMA: z.ZodObject<\n {\n ip: z.ZodUnion<readonly [z.ZodIPv4, z.ZodIPv6]>;\n location: z.ZodOptional<\n z.ZodObject<{ country_code: z.ZodString }, z.core.$loose>\n >;\n },\n z.core.$loose\n> = z.looseObject({\n ip: z.union([z.ipv4(), z.ipv6()]),\n location: z.looseObject({ country_code: z.string().length(2) }).optional(),\n});\nexport type ApiResponse = z.infer<typeof RESPONSE_SCHEMA>;\nconst BULK_RESPONSE_SCHEMA = z.record(z.string(), RESPONSE_SCHEMA);\ntype BulkApiResponse = z.infer<typeof BULK_RESPONSE_SCHEMA>;\n\nexport class IpapiIs {\n public readonly endpoints: string = \"https://api.ipapi.is/\";\n private loader: DataLoader<string, ApiResponse>;\n private readonly key?: string;\n\n public constructor() {\n this.loader = new DataLoader(\n async (ips: readonly string[]): Promise<ApiResponse[]> =>\n await this.batchLoadFn(ips),\n { maxBatchSize: 100 },\n );\n this.key = process.env.IPAPI_IS_KEY;\n }\n\n public async lookup(ip: string): Promise<ApiResponse> {\n return await this.loader.load(ip);\n }\n\n protected async batchLoadFn(ips: readonly string[]): Promise<ApiResponse[]> {\n let data: any = await ky\n .post(this.endpoints, { json: { ips, key: this.key } })\n .json();\n data = R.omit(data, [\"total_elapsed_ms\"]);\n const response: BulkApiResponse = BULK_RESPONSE_SCHEMA.parse(data);\n return ips.map((ip: string): ApiResponse => response[ip]!);\n }\n}\n",
22
- "import consola from \"consola\";\nimport type { Outbound } from \"../outbound\";\nimport { Inferrer } from \"./abc\";\n\nexport class InferrerEmby extends Inferrer {\n public readonly pattern: RegExp = /emby/i;\n\n public override async infer<T extends Outbound>(outbound: T): Promise<T> {\n outbound.emby = this.pattern.test(outbound.name);\n if (outbound.emby)\n consola.success(`${outbound.prettyName} ~ ${this.pattern}`);\n return outbound;\n }\n}\n",
23
- "import consola from \"consola\";\nimport type { Outbound } from \"../outbound\";\nimport { Inferrer } from \"./abc\";\n\nexport class InferrerInfo extends Inferrer {\n public readonly pattern: RegExp = /Expire|Traffic|剩余|ε₯—ι€εˆ°ζœŸ/iu;\n\n public override async infer<T extends Outbound>(outbound: T): Promise<T> {\n outbound.info = this.pattern.test(outbound.name);\n if (outbound.info)\n consola.success(`${outbound.prettyName} ~ ${this.pattern}`);\n return outbound;\n }\n}\n",
24
- "import type { Outbound } from \"../outbound\";\nimport { Inferrer } from \"./abc\";\nimport { InferrerCountry } from \"./country\";\nimport { InferrerEmby } from \"./emby\";\nimport { InferrerInfo } from \"./info\";\n\nexport class InferrerContainer extends Inferrer {\n public readonly inferrers: Inferrer[];\n\n public constructor(inferrers?: Inferrer[]) {\n super();\n if (!inferrers) {\n inferrers = [\n new InferrerEmby(),\n new InferrerInfo(),\n new InferrerCountry(), // `InferrerCountry` depends on `InferrerEmby` & `InferrerInfo`\n ];\n }\n this.inferrers = inferrers;\n }\n\n public override async infer<T extends Outbound>(outbound: T): Promise<T> {\n for (const inferrer of this.inferrers)\n outbound = await inferrer.infer(outbound);\n return outbound;\n }\n\n public override async inferBulk<T extends Outbound>(\n outbounds: T[],\n ): Promise<T[]> {\n return await Promise.all(\n outbounds.map((outbound: T): Promise<T> => this.infer(outbound)),\n );\n }\n}\n",
25
- "import fs from \"node:fs/promises\";\nimport YAML from \"yaml\";\nimport type { MihomoOutbound } from \"../formats\";\nimport { Provider } from \"./provider\";\nimport type { ProfileModel, ProviderOptions } from \"./schema\";\nimport { PROFILE_SCHEMA } from \"./schema\";\n\nexport class Profile {\n public providers: Provider[];\n\n static async load(file: string): Promise<Profile> {\n const data: string = await fs.readFile(file, \"utf8\");\n const parsed: any = YAML.parse(data);\n const profile: ProfileModel = PROFILE_SCHEMA.parse(parsed);\n return new Profile(profile.providers);\n }\n\n constructor(providers: readonly ProviderOptions[]) {\n this.providers = providers.map(\n (options: ProviderOptions): Provider => new Provider(options),\n );\n }\n\n async fetchMihomoOutbounds(): Promise<MihomoOutbound[]> {\n const outbounds = await Promise.all(\n this.providers.map((provider) => provider.fetchOutboundsMihomo()),\n );\n return outbounds.flat();\n }\n}\n",
26
- "import consola from \"consola\";\nimport ky from \"ky\";\nimport type { Mihomo, MihomoNode } from \"../formats\";\nimport { MihomoOutbound, mihomoParse } from \"../formats\";\nimport { PROVIDER_SCHEMA, type ProviderOptions } from \"./schema\";\nimport { subconvertUrl } from \"./subconvert\";\n\nexport class Provider {\n public readonly name: string;\n public readonly jms?: { url: string };\n public readonly mihomo?: { url: string };\n\n public constructor(options: ProviderOptions) {\n const { name, jms, mihomo } = PROVIDER_SCHEMA.parse(options);\n this.name = name;\n this.jms = jms;\n this.mihomo = mihomo;\n }\n\n public async fetchOutboundsMihomo(): Promise<MihomoOutbound[]> {\n const url: string | URL | undefined = this.getMihomoURL();\n if (!url) return [];\n const headers = new Headers({ \"User-Agent\": \"clash.meta\" });\n const text: string = await ky.get(url, { headers }).text();\n const config: Mihomo = mihomoParse(text);\n return config.proxies!.map(\n (proxy: MihomoNode): MihomoOutbound => new MihomoOutbound(proxy, this),\n );\n }\n\n protected warnFormat(format: string): void {\n consola.warn(`Provider '${this.name}' does not support '${format}'`);\n }\n\n protected getMihomoURL(): string | URL | undefined {\n if (this.mihomo) return this.mihomo.url;\n if (this.jms) return subconvertUrl(this.jms.url, \"clash\");\n this.warnFormat(\"mihomo\");\n return undefined;\n }\n}\n",
27
- "import { z } from \"zod\";\n\nexport const PROVIDER_SCHEMA: z.ZodObject<{\n name: z.ZodString;\n free: z.ZodDefault<z.ZodBoolean>;\n jms: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }, z.core.$strip>>;\n mihomo: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }, z.core.$strip>>;\n}> = z.object({\n name: z.string(),\n free: z.boolean().default(false),\n jms: z.object({ url: z.url() }).optional(),\n mihomo: z.object({ url: z.url() }).optional(),\n});\nexport type ProviderOptions = z.input<typeof PROVIDER_SCHEMA>;\n\nexport const PROFILE_SCHEMA: z.ZodObject<{\n providers: z.ZodArray<\n z.ZodObject<\n {\n name: z.ZodString;\n free: z.ZodDefault<z.ZodBoolean>;\n jms: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }, z.core.$strip>>;\n mihomo: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }, z.core.$strip>>;\n },\n z.core.$strip\n >\n >;\n}> = z.object({\n providers: z.array(PROVIDER_SCHEMA),\n});\nexport type ProfileModel = z.infer<typeof PROFILE_SCHEMA>;\n",
28
- "import ky from \"ky\";\n\nconst BACKEND: string = process.env.SUBCONVERTER_URL || \"https://url.v1.mk/sub\";\n\nexport function subconvertUrl(url: string, target: string): URL {\n const req = new URL(BACKEND);\n req.searchParams.set(\"url\", url);\n req.searchParams.set(\"target\", target);\n req.searchParams.set(\"list\", \"true\");\n return req;\n}\n\nexport async function subconvert(url: string, target: string): Promise<string> {\n const req: URL = subconvertUrl(url, target);\n return await ky.get(req).text();\n}\n",
17
+ "import fs from \"node:fs/promises\";\nimport * as R from \"remeda\";\nimport YAML from \"yaml\";\nimport type { Group } from \"../../group\";\nimport type { MihomoOutbound } from \"./outbound\";\nimport { mihomoParse } from \"./parse\";\nimport type {\n Mihomo,\n MihomoNode,\n MihomoProxyGroup,\n MihomoProxyGroupOptions,\n} from \"./schema\";\nimport { MIHOMO_PROXY_GROUP_SCHEMA } from \"./schema\";\n\nexport class MihomoTemplate {\n template: Mihomo;\n\n static async load(path: string): Promise<MihomoTemplate> {\n const template: string = await fs.readFile(path, \"utf8\");\n return new MihomoTemplate(template);\n }\n\n public constructor(template: string) {\n this.template = mihomoParse(template);\n }\n\n public render(outbounds: readonly MihomoOutbound[], groups: Group[]): string {\n let config: Mihomo = R.clone(this.template);\n config.proxies = outbounds.map((o: MihomoOutbound): MihomoNode => o.mihomo);\n const groupProxy: MihomoProxyGroup = this.renderGroupProxy();\n config[\"proxy-groups\"] = [groupProxy];\n for (const group of groups) {\n const rendered: MihomoProxyGroup | undefined = this.renderGroup(\n outbounds,\n group,\n );\n if (!rendered) continue;\n config[\"proxy-groups\"].push(rendered);\n groupProxy.proxies.push(rendered.name);\n }\n config = this.sanitize(config);\n return YAML.stringify(config, {\n aliasDuplicateObjects: false,\n sortMapEntries: true,\n });\n }\n\n protected sanitize(config: Mihomo): Mihomo {\n config = R.omitBy(config, (_value, key: string): boolean =>\n key.startsWith(\"__\"),\n );\n const outboundsNames: Set<string> = new Set([\n \"DIRECT\",\n \"REJECT\",\n \"REJECT-DROP\",\n \"PASS\",\n ]);\n for (const outbound of config.proxies || [])\n outboundsNames.add(outbound.name);\n for (const group of config[\"proxy-groups\"] || [])\n outboundsNames.add(group.name);\n if (config.rules) {\n config.rules = config.rules.filter((rule: string): boolean => {\n const parts: string[] = rule\n .split(\",\")\n .filter((p: string): boolean => p.trim() !== \"no-resolve\");\n const outbound: string = parts[parts.length - 1]!.trim();\n return outboundsNames.has(outbound);\n });\n }\n return config;\n }\n\n protected renderGroup(\n outbounds: readonly MihomoOutbound[],\n group: Group,\n ): MihomoProxyGroup | undefined {\n const filtered: MihomoOutbound[] = outbounds.filter(group.filter);\n if (filtered.length === 0) return undefined;\n const filteredNames: string[] = filtered.map(\n (o: MihomoOutbound): string => o.prettyName,\n );\n const options: MihomoProxyGroupOptions = {\n name: group.name,\n type: group.type,\n proxies: filteredNames,\n url: group.url,\n icon: group.icon,\n };\n return MIHOMO_PROXY_GROUP_SCHEMA.parse(options);\n }\n\n protected renderGroupProxy(): MihomoProxyGroup {\n const options: MihomoProxyGroupOptions = {\n name: \"PROXY\",\n type: \"select\",\n proxies: [],\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png\",\n };\n return MIHOMO_PROXY_GROUP_SCHEMA.parse(options);\n }\n}\n",
18
+ "import type { Outbound } from \"../core\";\nimport type { Group } from \"./base\";\n\nexport function good(outbound: Outbound): boolean {\n // connection quality of Hysteria2 is poor\n return !outbound.emby && !outbound.info && outbound.type !== \"hysteria2\";\n}\n\nexport const PROXY: Group = {\n name: \"PROXY\",\n type: \"select\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png\",\n filter(_outbound: Outbound): boolean {\n return false;\n },\n};\n\nexport const INFO: Group = {\n name: \"Info\",\n type: \"url-test\",\n emoji: \"ℹ️\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png\",\n filter(outbound: Outbound): boolean {\n return outbound.info;\n },\n};\n\nexport const AUTO: Group = {\n name: \"Auto\",\n type: \"url-test\",\n emoji: \"πŸš€\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Auto.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier <= 2.0;\n },\n};\n\nconst BINANCE_EXCLUDE_REGIONS = new Set([\n \"CA\",\n \"CN\",\n \"CU\",\n \"HK\",\n \"IR\",\n \"KP\",\n \"MO\",\n \"NL\",\n \"TW\",\n \"US\",\n]);\nexport const BINANCE: Group = {\n name: \"Binance\",\n type: \"url-test\",\n emoji: \"πŸͺ™\",\n // TODO: add icon\n url: \"https://api.binance.com/api/v3/ping\",\n filter(outbound: Outbound): boolean {\n return (\n good(outbound) &&\n !!outbound.country &&\n !BINANCE_EXCLUDE_REGIONS.has(outbound.country.cca2)\n );\n },\n};\n\nconst AI_EXCLUDE_REGIONS = new Set([\"HK\", \"MO\"]);\nexport const AI: Group = {\n name: \"AI\",\n type: \"url-test\",\n emoji: \"πŸ€–\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/AI.png\",\n filter(outbound: Outbound): boolean {\n return (\n good(outbound) &&\n !!outbound.country &&\n !AI_EXCLUDE_REGIONS.has(outbound.country.cca2)\n );\n },\n};\n\nexport const DOWNLOAD: Group = {\n name: \"Download\",\n type: \"url-test\",\n emoji: \"πŸ“₯\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Download.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier <= 1.0;\n },\n};\n\nexport const STREAM: Group = {\n name: \"Stream\",\n type: \"url-test\",\n emoji: \"πŸ“Ί\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/YouTube.png\",\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.multiplier < 2.0;\n },\n};\n",
19
+ "import countries, { type Country } from \"world-countries\";\nimport { COUNTRY_UNKNOWN } from \"../utils\";\nimport type { Group } from \"./base\";\nimport { AI, AUTO, BINANCE, INFO, STREAM } from \"./common\";\nimport { newCountryGroup } from \"./country\";\n\nexport function defaultGroups(): Group[] {\n return [\n AUTO,\n INFO,\n AI,\n BINANCE,\n // CITRUSLAB_EMBY,\n // DOWNLOAD,\n STREAM,\n ...countries.map((c: Country): Group => newCountryGroup(c)),\n newCountryGroup(COUNTRY_UNKNOWN),\n ];\n}\n",
20
+ "import twemoji from \"@twemoji/api\";\nimport type { Country } from \"world-countries\";\nimport type { Outbound } from \"../core\";\nimport type { Group } from \"./base\";\nimport { good } from \"./common\";\n\nexport function newCountryGroup(\n country: Country,\n options?: { type?: \"select\" | \"url-test\" },\n): Group {\n const { cca2, flag } = country;\n const codePoint: string = twemoji.convert.toCodePoint(flag);\n const icon: string = \"\".concat(\n twemoji.base,\n twemoji.size,\n \"/\",\n codePoint,\n twemoji.ext,\n );\n return {\n name: country.name.common,\n type: options?.type ?? \"url-test\",\n emoji: flag,\n icon,\n filter(outbound: Outbound): boolean {\n return good(outbound) && outbound.country.cca2 === cca2;\n },\n };\n}\n",
21
+ "import type { Outbound } from \"../core\";\n\nexport abstract class Processor {\n async process<O extends Outbound>(outbounds: O[]): Promise<O[]> {\n return await Promise.all(\n outbounds.map(async (o: O): Promise<O> => await this.processOne(o)),\n );\n }\n\n abstract processOne<T extends Outbound>(outbound: T): Promise<T>;\n}\n",
22
+ "import consola from \"consola\";\nimport countries, { type Country } from \"world-countries\";\nimport type { Outbound } from \"../core\";\nimport type { GeoIpApiResponse } from \"../utils\";\nimport { COUNTRY_UNKNOWN, GeoIP, lookupCountry } from \"../utils\";\nimport { Processor } from \"./base\";\n\nexport class ProcessorCountry extends Processor {\n private readonly geoip: GeoIP = new GeoIP();\n\n public override async processOne<O extends Outbound>(\n outbound: O,\n ): Promise<O> {\n if (outbound.emby || outbound.info) {\n outbound.country = COUNTRY_UNKNOWN;\n return outbound;\n }\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2)\n outbound = this.inferFromName(outbound);\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2)\n outbound = await this.inferFromServer(outbound);\n if (outbound.country.cca2 === COUNTRY_UNKNOWN.cca2) {\n consola.fail(\n `${outbound.prettyName} (${prettyCountry(outbound.country)})`,\n );\n }\n return outbound;\n }\n\n protected inferFromName<T extends Outbound>(outbound: T): T {\n const name: string = outbound.name;\n for (const country of countries) {\n if (country.cca2 === \"CN\") continue;\n for (const pattern of patterns(country)) {\n if (!pattern) continue;\n if (pattern.test(name)) {\n consola.success(\n `${outbound.prettyName} ~ ${pattern} (${prettyCountry(country)})`,\n );\n outbound.country = country;\n return outbound;\n }\n }\n }\n return outbound;\n }\n\n protected async inferFromServer<T extends Outbound>(outbound: T): Promise<T> {\n const response: GeoIpApiResponse = await this.geoip.lookup(outbound.server);\n if (response.location?.country_code) {\n outbound.country =\n lookupCountry(response.location.country_code) || COUNTRY_UNKNOWN;\n } else {\n outbound.country = COUNTRY_UNKNOWN;\n }\n if (outbound.country.cca2 !== COUNTRY_UNKNOWN.cca2) {\n consola.success(\n `${outbound.prettyName} -> ${response.ip} (${prettyCountry(outbound.country)})`,\n );\n }\n return outbound;\n }\n}\n\nfunction* patterns(country: Country): Generator<RegExp | undefined> {\n const EXCLUDE_PATTERNS = new Set([\n \"GB\", // gigabyte\n ]);\n\n function short(pattern?: string): RegExp | undefined {\n if (!pattern) return undefined;\n if (EXCLUDE_PATTERNS.has(pattern)) return undefined;\n return new RegExp(`\\\\b${pattern}\\\\b`);\n }\n\n function long(pattern?: string): RegExp | undefined {\n if (!pattern) return undefined;\n if (EXCLUDE_PATTERNS.has(pattern)) return undefined;\n return new RegExp(pattern, \"iu\");\n }\n\n for (const locale of [\"en\", \"zh\"]) {\n for (const style of [\"narrow\", \"short\", \"long\"]) {\n const display = new Intl.DisplayNames(locale, {\n style: style as Intl.RelativeTimeFormatStyle,\n type: \"region\",\n });\n if (style === \"narrow\" || style === \"short\") {\n yield short(display.of(country.cca2));\n } else if (style === \"long\") {\n yield long(display.of(country.cca2));\n }\n }\n }\n yield long(country.name.common);\n yield long(country.name.official);\n for (const lang in country.name.native) {\n yield long(country.name.native[lang]!.common);\n yield long(country.name.native[lang]!.official);\n }\n yield short(country.cca2);\n // yield long(country.ccn3);\n yield short(country.cca3);\n yield short(country.cioc);\n for (const capital of country.capital) yield long(capital);\n // for (const alt of country.altSpellings) yield long(alt);\n yield long(country.flag);\n}\n\nfunction prettyCountry(country: Country): string {\n return `${country.flag} ${country.name.common} (${country.cca2})`;\n}\n",
23
+ "import consola from \"consola\";\nimport type { Outbound } from \"../core\";\nimport { Processor } from \"./base\";\n\nexport class ProcessorInfo extends Processor {\n public readonly pattern: RegExp = /Expire|Traffic|剩余|ε₯—ι€εˆ°ζœŸ/iu;\n\n public override async processOne<O extends Outbound>(\n outbound: O,\n ): Promise<O> {\n outbound.info = this.pattern.test(outbound.name);\n if (outbound.info)\n consola.success(`${outbound.prettyName} ~ ${this.pattern}`);\n return outbound;\n }\n}\n",
24
+ "import fs from \"node:fs/promises\";\nimport YAML from \"yaml\";\nimport { z } from \"zod\";\nimport { Provider } from \"./core\";\nimport type { MihomoOutbound } from \"./formats\";\n\nexport const PROVIDER_SCHEMA: z.ZodObject<{\n name: z.ZodString;\n free: z.ZodDefault<z.ZodBoolean>;\n jms: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }>>;\n mihomo: z.ZodOptional<z.ZodObject<{ url: z.ZodURL }>>;\n}> = z.object({\n name: z.string(),\n free: z.boolean().default(false),\n jms: z.object({ url: z.url() }).optional(),\n mihomo: z.object({ url: z.url() }).optional(),\n});\nexport type ProviderOptions = z.input<typeof PROVIDER_SCHEMA>;\n\nexport const PROFILE_SCHEMA: z.ZodObject<{\n providers: z.ZodArray<typeof PROVIDER_SCHEMA>;\n}> = z.object({\n providers: z.array(PROVIDER_SCHEMA),\n});\nexport type ProfileModel = z.infer<typeof PROFILE_SCHEMA>;\n\nexport class Profile {\n public providers: Provider[];\n\n static async load(file: string): Promise<Profile> {\n const data: string = await fs.readFile(file, \"utf8\");\n const parsed: any = YAML.parse(data);\n const profile: ProfileModel = PROFILE_SCHEMA.parse(parsed);\n return new Profile(profile.providers);\n }\n\n constructor(providers: readonly ProviderOptions[]) {\n this.providers = providers.map(\n (options: ProviderOptions): Provider => new Provider(options),\n );\n }\n\n async fetchMihomoOutbounds(): Promise<MihomoOutbound[]> {\n const outbounds: MihomoOutbound[][] = await Promise.all(\n this.providers.map(\n async (provider: Provider): Promise<MihomoOutbound[]> =>\n await provider.fetchOutboundsMihomo(),\n ),\n );\n return outbounds.flat();\n }\n}\n",
29
25
  "import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { StricliAutoCompleteContext } from \"@stricli/auto-complete\";\nimport type { CommandContext } from \"@stricli/core\";\n\nexport interface Context extends CommandContext, StricliAutoCompleteContext {\n readonly process: NodeJS.Process;\n}\n\nexport const context: Context = { process, os, fs, path };\n"
30
26
  ],
31
- "mappings": "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",
32
- "debugId": "D8736C8FA46E4ED164756E2164756E21",
27
+ "mappings": "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",
28
+ "debugId": "F0D751FFD124BACE64756E2164756E21",
33
29
  "names": []
34
30
  }
package/package.json CHANGED
@@ -1,12 +1,24 @@
1
1
  {
2
2
  "name": "@liblaf/sub-store",
3
+ "version": "0.1.11",
3
4
  "description": "",
4
- "version": "0.1.9",
5
+ "keywords": [],
6
+ "homepage": "https://github.com/liblaf/sub-store",
7
+ "bugs": {
8
+ "url": "https://github.com/liblaf/sub-store/issues"
9
+ },
10
+ "repository": "github:liblaf/sub-store",
11
+ "funding": {
12
+ "type": "github",
13
+ "url": "https://github.com/liblaf/sub-store?sponsor=1"
14
+ },
15
+ "license": "MIT",
16
+ "author": {
17
+ "name": "liblaf",
18
+ "email": "30631553+liblaf@users.noreply.github.com",
19
+ "url": "https://github.com/liblaf"
20
+ },
5
21
  "type": "module",
6
- "files": [
7
- "dist"
8
- ],
9
- "module": "./dist/index.js",
10
22
  "exports": {
11
23
  ".": {
12
24
  "import": "./dist/index.js"
@@ -16,66 +28,51 @@
16
28
  },
17
29
  "./package.json": "./package.json"
18
30
  },
19
- "keywords": [],
20
- "homepage": "https://github.com/liblaf/sub-store",
21
- "bugs": {
22
- "url": "https://github.com/liblaf/sub-store/issues"
23
- },
24
- "license": "MIT",
25
- "author": {
26
- "name": "liblaf",
27
- "url": "https://github.com/liblaf",
28
- "email": "30631553+liblaf@users.noreply.github.com"
29
- },
31
+ "module": "./dist/index.js",
30
32
  "bin": {
31
33
  "sub-store": "./dist/bin/sub-store.js"
32
34
  },
33
- "repository": {
34
- "type": "git",
35
- "url": "git+https://github.com/liblaf/sub-store.git"
36
- },
37
- "funding": {
38
- "url": "https://github.com/liblaf/sub-store?sponsor=1",
39
- "type": "github"
40
- },
35
+ "files": [
36
+ "dist"
37
+ ],
41
38
  "scripts": {
42
39
  "build": "bunup",
43
- "format:fix": "biome format --write",
44
40
  "format": "biome format",
45
- "lint:fix": "biome check --write",
41
+ "format:fix": "biome format --write",
46
42
  "lint": "biome check",
43
+ "lint:fix": "biome check --write",
47
44
  "prepack": "npm run build",
45
+ "test": "bun test",
48
46
  "test:coverage": "bun test --coverage",
49
47
  "test:watch": "bun test --watch",
50
- "test": "bun test",
51
48
  "tsc": "tsc --noEmit"
52
49
  },
53
50
  "dependencies": {
54
- "@stricli/auto-complete": "^1",
55
- "@stricli/core": "^1",
56
- "@twemoji/api": "^17",
57
- "consola": "^3",
58
- "dataloader": "^2",
59
- "ky": "^1",
60
- "remeda": "^2",
61
- "world-countries": "^5",
62
- "yaml": "^2",
63
- "zod": "^4"
51
+ "@stricli/core": "^1.2.4",
52
+ "@twemoji/api": "^17.0.2",
53
+ "consola": "^3.4.2",
54
+ "dataloader": "^2.2.3",
55
+ "ky": "^1.14.1",
56
+ "remeda": "^2.32.0",
57
+ "world-countries": "^5.1.0",
58
+ "yaml": "^2.8.2",
59
+ "zod": "^4.1.13"
64
60
  },
65
61
  "devDependencies": {
66
- "@biomejs/biome": "^2",
67
- "@liblaf/config": "^0.1",
68
- "@types/bun": "^1",
69
- "bunup": "^0.15",
70
- "prettier": "^3"
62
+ "@biomejs/biome": "^2.3.8",
63
+ "@liblaf/config": "^0.1.1",
64
+ "@stricli/auto-complete": "^1.2.4",
65
+ "@types/bun": "^1.3.4",
66
+ "bunup": "^0.16.10",
67
+ "prettier": "^3.7.4"
71
68
  },
72
69
  "peerDependencies": {
73
- "typescript": "^5"
70
+ "typescript": "^5.9.2"
74
71
  },
75
72
  "publishConfig": {
76
73
  "access": "public",
77
- "registry": "https://registry.npmjs.org/",
78
- "provenance": true
74
+ "provenance": true,
75
+ "registry": "https://registry.npmjs.org/"
79
76
  },
80
77
  "readme": "README.md"
81
78
  }