@liblaf/sub-store 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/bin/sub-store.d.ts +0 -0
- package/dist/bin/sub-store.js +6 -0
- package/dist/bin/sub-store.js.map +31 -0
- package/dist/chunk-7rje8aby.js +5 -0
- package/dist/chunk-7rje8aby.js.map +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +9 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 liblaf
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env -S bun
|
|
2
|
+
// @bun
|
|
3
|
+
import{a as d}from"../chunk-7rje8aby.js";import ae from"fs";import le from"os";import ue from"path";import{run as de}from"@stricli/core";import{buildApplication as me,buildRouteMap as pe}from"@stricli/core";var $="TODO",z="0.0.0";import X from"fs/promises";import{buildCommand as re}from"@stricli/core";import ie from"yaml";import{z as ne}from"zod/v4";import fo from"yaml";function u(o){return fo.parse(o,{merge:!0})}import m from"zod/v4";var ao="https://cp.cloudflare.com",S=m.int().min(1).max(65535),T=m.looseObject({name:m.string(),server:m.string()}),M=m.looseObject({name:m.string(),type:m.enum(["select","url-test"]),proxies:m.array(m.string()),url:m.url().default(ao).optional(),interval:m.int().positive().default(300).optional(),lazy:m.boolean().default(!0).optional(),icon:m.string().optional()}),q=m.looseObject({"mixed-port":S.default(7892).optional(),proxies:m.array(T).optional(),"proxy-groups":m.array(M).optional()});import*as E from"remeda";import lo from"yaml";import uo from"zod/v4";var co=uo.object({port:S.default(7890)});class A{options;template;constructor(o,e){this.template=u(o),this.options=co.parse(e)}render(o,e){let r=E.clone(this.template);r.proxies=o.map((n)=>n.mihomo).filter((n)=>n!==void 0);let i=this.renderGroupDefault();r["proxy-groups"]=[i];for(let n of e){let s=this.renderGroup(o,n);if(!s)continue;r["proxy-groups"].push(s),i.proxies.push(s.name)}return r["mixed-port"]=this.options.port,r=this.sanitize(r),lo.stringify(r,{aliasDuplicateObjects:!1})}sanitize(o){return o=E.omitBy(o,(e,r)=>r.startsWith("__")),o}renderGroupDefault(){let o={name:"PROXY",type:"select",proxies:[],icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Proxy.png"};return M.parse(o)}renderGroup(o,e){let r=o.filter(e.filter);if(r.length===0)return;let i={name:e.name,type:e.type,proxies:r.map((n)=>n.prettyName),url:e.url,icon:e.icon};return M.parse(i)}}import{Cacheable as bo}from"@type-cacheable/core";import{LRUCacheAdapter as Po}from"@type-cacheable/lru-cache-adapter";import J from"ky";import{LRUCache as ho}from"lru-cache";import*as a from"remeda";import C from"zod/v4";var go=new ho({max:1024}),D=new Po(go),xo=C.object({key:C.string(),url:C.url().default("https://api.ipapi.is/"),maxBulkSize:C.int().positive().default(100)});class P{key;url;maxBulkSize;constructor(o){let{key:e,url:r,maxBulkSize:i}=xo.parse(o);this.key=e,this.url=r,this.maxBulkSize=i}async lookup(o){let e=new URL(this.url);return await J.get(e,{searchParams:{q:o,key:this.key}}).json()}async bulk(o){o=a.unique(o);let e=Object.fromEntries(await Promise.all(o.map(async(s)=>[s,await D.get(s)]))),r=o.filter((s)=>!e[s]),i=a.mergeAll(await Promise.all(a.chunk(r,this.maxBulkSize).map(async(s)=>await this._bulk(s))));return a.merge(e,i)}async _bulk(o){let e=await J.post(this.url,{json:{ips:o,key:this.key}}).json();return delete e.total_elapsed_ms,await Promise.all(Object.entries(e).map(async([r,i])=>{await D.set(r,i)})),e}}d([bo({cacheKey(o,e){return o[0]},client:D})],P.prototype,"lookup",null);import*as Z from"remeda";import So from"world-countries";import F from"dns";import{LRUCacheAdapter as Oo}from"@type-cacheable/lru-cache-adapter";import{LRUCache as _o}from"lru-cache";import{z as W}from"zod/v4";import{Logger as yo}from"tslog";function l(o,e){return new yo(o,e)}var Fe=l();var L=l(),Io=new _o({max:1024}),c=new Oo(Io);class Y{async resolveIP(o){if(R(o))return[o];let e=[];e.push(...await this.resolve4(o)),e.push(...await this.resolve6(o));let r=await this.resolveCname(o);return e.push(...(await Promise.all(r.map(async(i)=>await this.resolveIP(i)))).flat()),e}async resolve4(o){if(R(o))return[o];let e=`A:${o}`,r=await c.get(e);if(r!==void 0)return r;let i=[];try{i=await F.promises.resolve4(o)}catch(n){L.debug(`${n}`)}return await c.set(e,i),i}async resolve6(o){if(R(o))return[o];let e=`AAAA:${o}`,r=await c.get(e);if(r!==void 0)return r;let i=[];try{i=await F.promises.resolve6(o)}catch(n){L.debug(`${n}`)}return await c.set(e,i),i}async resolveCname(o){if(R(o))return[o];let e=`CNAME:${o}`,r=await c.get(e);if(r!==void 0)return r;let i=[];try{i=await F.promises.resolveCname(o)}catch(n){L.debug(`${n}`)}return await c.set(e,i),i}}function R(o){return W.ipv4().safeParse(o).success||W.ipv6().safeParse(o).success}class h{api;dns=new Y;countries=Object.fromEntries(So.map((o)=>[o.cca2,o]));constructor(o){this.api=new P(o)}async lookup(o){let e=await this.dns.resolveIP(o);if(e.length===0)return;let r=e[0],i=await this.api.lookup(r);return this.countries[i.location.country_code]}async bulk(o){o=Z.unique(o);let e=Object.fromEntries(await Promise.all(o.map(async(n)=>{let s=await this.dns.resolveIP(n);return[n,s[0]]}))),r=await this.api.bulk(Object.values(e).filter((n)=>n!==void 0)),i={};for(let n of o){let s=e[n];if(!s){i[n]=void 0;continue}let _=r[s]?.location?.country_code;if(!_){i[n]=void 0;continue}i[n]=this.countries[_]}return i}}import t from"zod/v4";var Mo=t.object({service:t.string(),url:t.string(),type:t.string(),last_seen:t.number(),last_seen_str:t.string(),exit_node_region:t.string(),country_code:t.string(),city_name:t.string(),latitude:t.number(),longitude:t.number()}),Eo=t.object({datacenter:t.string(),domain:t.string(),network:t.string()}),Ao=t.object({name:t.string(),abuser_score:t.string(),domain:t.string(),type:t.string(),network:t.string(),whois:t.string()}),tt=t.object({name:t.string(),address:t.string(),country:t.string(),email:t.string(),phone:t.string()}),Co=t.object({asn:t.number().int(),abuser_score:t.string(),route:t.string(),descr:t.string(),country:t.string(),active:t.string(),org:t.string(),domain:t.string(),abuse:t.string(),type:t.string(),created:t.string(),updated:t.string(),rir:t.string(),whois:t.string()}),Ro=t.object({is_eu_member:t.boolean(),calling_code:t.string(),currency_code:t.string(),continent:t.string(),country:t.string(),country_code:t.string(),state:t.string(),city:t.string(),latitude:t.number(),longitude:t.number(),zip:t.string(),timezone:t.string(),local_time:t.string(),local_time_unix:t.number().int(),is_dst:t.boolean(),other:t.array(t.any()).optional()}),B=t.object({ip:t.string(),rir:t.string(),is_bogon:t.boolean(),is_mobile:t.boolean(),is_satellite:t.boolean(),is_crawler:t.boolean(),is_datacenter:t.boolean(),is_tor:t.boolean(),is_proxy:t.boolean(),is_vpn:t.boolean(),is_abuser:t.boolean(),elapsed_ms:t.number(),vpn:Mo,datacenter:Eo,company:Ao,asn:Co,location:Ro}),oo=t.record(t.string(),B);import wo from"world-countries";function jo(o){let e=o?.cca2.toLowerCase()??"un";return{name:o?o.name.common:"Unknown",type:o?"url-test":"select",emoji:o?o.flag:"\uD83C\uDDFA\uD83C\uDDF3",icon:`https://flagcdn.com/256x192/${e}.png`,filter(r){if(r.emby||r.placeholder)return!1;if(!o)return r.country===void 0;if(!r.country)return!1;return r.country===o.cca2}}}var Ho={name:"Select",type:"select",emoji:"",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Static.png",filter(o){return!0}},eo={name:"Auto",type:"url-test",emoji:"\uD83D\uDE80",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Auto.png",filter(o){if(o.emby||o.placeholder)return!1;return o.multiplier<=2}},No=new Set(["CN","HK","MO"]),Go={name:"AI",type:"url-test",emoji:"\uD83E\uDD16",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/AI.png",filter(o){if(o.emby||o.placeholder)return!1;return!!o.country&&!No.has(o.country)}},vo={name:"Download",type:"url-test",emoji:"\uD83D\uDCE5",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Download.png",filter(o){if(o.emby||o.placeholder)return!1;return o.multiplier<=1}},ko={name:"Stream",type:"url-test",emoji:"\uD83D\uDCFA",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/YouTube.png",filter(o){if(o.emby||o.placeholder)return!1;return o.multiplier<2}},To={name:"Info",type:"select",emoji:"\u2139\uFE0F",icon:"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png",filter(o){return o.placeholder}},Do={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(o){return o.emby&&o.provider==="CitrusLab"}};function U(){return[eo,Ho,To,Go,vo,ko,Do,...wo.map(jo)]}class w{provider;overrides;connection;country;emby=!1;multiplier=1;placeholder=!1;_mihomo;constructor(o){this.provider=o.provider,this.overrides=o.overrides??{},this._mihomo=o.mihomo}get name(){if(this.provider==="JMS"){let o=this._mihomo.name.match(/@(?<name>[\w-]+)/);if(o)return o.groups?.name??this._mihomo.name}return this._mihomo.name}get prettyName(){if(this.provider)return`[${this.provider}]${this.name}`;return this.name}get server(){return this._mihomo.server}get mihomo(){if(!this._mihomo)return;return{...this._mihomo,name:this.prettyName}}}import{Cacheable as Yo}from"@type-cacheable/core";import{LRUCacheAdapter as Bo}from"@type-cacheable/lru-cache-adapter";import{LRUCache as Uo}from"lru-cache";import Ko from"world-countries";var to=l(),Qo=new Uo({max:512}),Xo=new Bo(Qo);class g{geoip;constructor(o){this.geoip=o?.geoip}async infer(o){let e=await this._infer(o);if(e==="Unknown")return;return e}prettyCountry(o){if(!o)return"Unknown";return`${o.flag} ${o.name.common} (${o.cca2})`}async _infer(o){let e;if(e=await this.inferFromName(o.name),e)return e;if(e=await this.inferFromServer(o),e)return e;return"Unknown"}async inferFromServer(o){if(!o.server)return;if(!this.geoip)return;let e=await this.geoip.lookup(o.server);if(to.debug(`Country: ${o.name} => ${o.server} => ${this.prettyCountry(e)}`),e?.cca2==="CN")return;return e}async inferFromName(o){if(!o)return;for(let e of Ko){if(e.cca2==="CN")continue;for(let r of Vo(e))if(o.match(r))return to.debug(`Country: ${o} =~ ${r} ${this.prettyCountry(e)}`),e}}}d([Yo({client:Xo})],g.prototype,"_infer",null);function*Vo(o){for(let e of $o(o)){if(!e)continue;yield e}}function*$o(o){for(let e of["en","zh"])for(let r of["narrow","short","long"]){let i=new Intl.DisplayNames(e,{style:r,type:"region"});if(r==="narrow"||r==="short")yield j(i.of(o.cca2));else if(r==="long")yield b(i.of(o.cca2))}yield b(o.name.common),yield b(o.name.official);for(let e in o.name.native)yield b(o.name.native[e].common),yield b(o.name.native[e].official);yield j(o.cca2),yield j(o.cca3),yield j(o.cioc);for(let e of o.capital)yield b(e)}var zo=new Set(["GB"]);function j(o){if(!o)return;if(zo.has(o))return;return new RegExp(`\\b${o}\\b`)}function b(o){if(!o)return;return new RegExp(o,"i")}class x{infer(o){return!!o.name.match(/emby/i)}}class y{infer(o){if(o.overrides.multiplier!==void 0)return o.overrides.multiplier;let e=o.name.match(/(([0-9]*[.])?[0-9]+)x/i);if(e)return Number.parseFloat(e[1]);return 1}}class O{infer(o){if(o.name.match(/\u5269\u4F59\u6D41\u91CF|\u8DDD\u79BB\u4E0B\u6B21\u91CD\u7F6E\u5269\u4F59|\u5957\u9910\u5230\u671F/i))return!0;return!1}}import ro from"zod/v4";import{Cacheable as qo}from"@type-cacheable/core";import{useAdapter as Jo}from"@type-cacheable/lru-cache-adapter";import Wo from"ky";import{LRUCache as Zo}from"lru-cache";import H from"zod/v4";var oe=new Zo({max:8}),ee=Jo(oe,void 0,{excludeContext:!1}),te=H.object({url:H.url(),target:H.string(),backend:H.string().default("https://url.v1.mk/sub")});class K{async subconvert(o){let{url:e,target:r,backend:i}=te.parse(o),n=new URL(i);return n.searchParams.set("url",e),n.searchParams.set("target",r),n.searchParams.set("list","true"),await this.fetchText(n)}async fetchText(o,e){let r=new Headers;if(e)r.set("User-Agent",e);return await Wo.get(o,{headers:r}).text()}}d([qo({client:ee})],K.prototype,"fetchText",null);var N=new K;import f from"zod/v4";var G=f.object({name:f.string(),free:f.boolean().default(!1),mihomo:f.object({url:f.url(),ua:f.string().default("clash.meta")}).optional(),jms:f.object({api:f.url().optional(),url:f.url()}).optional()});class v{name;free;mihomo;jms;_mihomo;constructor(o){let e=G.parse(o);this.name=e.name,this.free=e.free,this.mihomo=e.mihomo,this.jms=e.jms}async fetchMihomo(){if(!this._mihomo){let o="";if(this.mihomo)o=await N.fetchText(this.mihomo.url,this.mihomo.ua);else if(this.jms)o=await N.subconvert({url:this.jms.url,target:"clash"});this._mihomo=u(o)}return this._mihomo}async fetchMihomoOutbounds(){return(await this.fetchMihomo()).proxies.map((e)=>new w({provider:this.name,mihomo:e}))}}var Q=ro.object({providers:ro.array(G)});class k{profile;providers;constructor(o){this.profile=Q.parse(o),this.providers=this.profile.providers.map((e)=>new v(e))}async fetchMihomoOutbounds(){return(await Promise.all(this.providers.map(async(e)=>await e.fetchMihomoOutbounds()))).flat()}async servers(){throw new Error("Not Implemented")}}var se=ne.coerce.number().int().min(1).max(65535).default(7890),io=re({docs:{brief:"mihomo"},async func(o){let e=new A(o.template,{port:o.port}),r=o.key?new h({key:o.key}):void 0,i=o.profile,n=new g({geoip:r}),s=new x,_=new y,so=new O,I=await i.fetchMihomoOutbounds();await r?.bulk(I.map((p)=>p.server)),I=await Promise.all(I.map(async(p)=>{return p.country=(await n.infer(p))?.cca2,p.emby=s.infer(p),p.multiplier=_.infer(p),p.placeholder=so.infer(p),p}));let mo=U(),po=e.render(I,mo);await X.writeFile(o.output,po)},parameters:{flags:{key:{kind:"parsed",parse:String,brief:"key",default:void 0,optional:!0},output:{kind:"parsed",parse:String,brief:"output",default:"config.yaml"},port:{kind:"parsed",parse:se.parse,brief:"port",default:"7890"},profile:{kind:"parsed",async parse(o){let e=await X.readFile(o,"utf-8"),r=ie.parse(e);return new k(r)},brief:"profile",default:"profile.yaml"},template:{kind:"parsed",async parse(o){return await X.readFile(o,"utf-8")},brief:"template",default:"templates/mihomo/default.yaml"}}}});var fe=pe({routes:{mihomo:io},docs:{brief:$}}),no=me(fe,{name:"sub-store",versionInfo:{currentVersion:z}});var ce={process,os:le,fs:ae,path:ue};await de(no,process.argv.slice(2),ce);
|
|
4
|
+
|
|
5
|
+
//# debugId=E1166A616C5684F264756E2164756E21
|
|
6
|
+
//# sourceMappingURL=sub-store.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/bin/sub-store.ts", "../src/cli/app.ts", "../src/cli/mihomo.ts", "../src/formats/mihomo/parser.ts", "../src/formats/mihomo/schema.ts", "../src/formats/mihomo/template.ts", "../src/geoip/ipapi.is/api.ts", "../src/geoip/ipapi.is/geoip.ts", "../src/geoip/dns.ts", "../src/utils/logging.ts", "../src/utils/fetch.ts", "../src/geoip/ipapi.is/schema.ts", "../src/groups/defaults.ts", "../src/outbound/outbound.ts", "../src/infer/country/inferrer.ts", "../src/infer/emby/inferrer.ts", "../src/infer/multiplier/inferrer.ts", "../src/infer/placeholder/inferrer.ts", "../src/store/schema.ts", "../src/provider/fetch.ts", "../src/provider/provider.ts", "../src/store/store.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"#!/usr/bin/env -S bun\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { StricliAutoCompleteContext } from \"@stricli/auto-complete\";\nimport { type CommandContext, run } from \"@stricli/core\";\nimport { app } from \"../cli/app\";\n\ninterface Context extends CommandContext, StricliAutoCompleteContext {\n readonly process: NodeJS.Process;\n}\n\nconst context: Context = { process, os, fs, path };\n\nawait run(app, process.argv.slice(2), context);\n",
|
|
6
|
+
"import { buildApplication, buildRouteMap } from \"@stricli/core\";\nimport { description, version } from \"../../package.json\";\nimport { mihomo } from \"./mihomo\";\n\nconst routes = buildRouteMap({\n routes: { mihomo },\n docs: { brief: description },\n});\n\nexport const app = buildApplication(routes, {\n name: \"sub-store\",\n versionInfo: { currentVersion: version },\n});\n",
|
|
7
|
+
"import fs from \"node:fs/promises\";\nimport { buildCommand, type CommandContext } from \"@stricli/core\";\nimport YAML from \"yaml\";\nimport { z } from \"zod/v4\";\nimport { MihomoTemplate } from \"../formats/mihomo\";\nimport { GeoIP } from \"../geoip\";\nimport { defaultGroups, type Group } from \"../groups\";\nimport {\n CountryInferrer,\n EmbyInferrer,\n MultiplierInferrer,\n PlaceholderInferrer,\n} from \"../infer\";\nimport type { Outbound } from \"../outbound\";\nimport type { ProfileParams } from \"../store\";\nimport { SubStore } from \"../store\";\n\ntype Flags = {\n key?: string;\n output: string;\n port: number;\n profile: SubStore;\n template: string;\n};\n\nconst PORT_SCHEMA = z.coerce.number().int().min(1).max(65535).default(7890);\n\nexport const mihomo = buildCommand({\n docs: {\n brief: \"mihomo\",\n },\n async func(this: CommandContext, flags: Flags): Promise<void> {\n const template = new MihomoTemplate(flags.template, { port: flags.port });\n const geoip: GeoIP | undefined = flags.key\n ? new GeoIP({ key: flags.key })\n : undefined;\n const store: SubStore = flags.profile;\n const countryInferrer = new CountryInferrer({ geoip });\n const embyInferrer = new EmbyInferrer();\n const multiplierInferrer = new MultiplierInferrer();\n const placeholderInferrer = new PlaceholderInferrer();\n\n let outbounds: Outbound[] = await store.fetchMihomoOutbounds();\n await geoip?.bulk(\n outbounds.map((outbound: Outbound): string => outbound.server),\n ); // warmup GeoIP cache\n outbounds = await Promise.all(\n outbounds.map(async (outbound: Outbound): Promise<Outbound> => {\n outbound.country = (await countryInferrer.infer(outbound))?.cca2;\n outbound.emby = embyInferrer.infer(outbound);\n outbound.multiplier = multiplierInferrer.infer(outbound);\n outbound.placeholder = placeholderInferrer.infer(outbound);\n return outbound;\n }),\n );\n\n const groups: Group[] = defaultGroups();\n const mihomo: string = template.render(outbounds, groups);\n await fs.writeFile(flags.output, mihomo);\n },\n parameters: {\n flags: {\n key: {\n kind: \"parsed\",\n parse: String,\n brief: \"key\",\n default: undefined,\n optional: true,\n },\n output: {\n kind: \"parsed\",\n parse: String,\n brief: \"output\",\n default: \"config.yaml\",\n },\n port: {\n kind: \"parsed\",\n parse: PORT_SCHEMA.parse,\n brief: \"port\",\n default: \"7890\",\n },\n profile: {\n kind: \"parsed\",\n async parse(profile: string): Promise<SubStore> {\n const text: string = await fs.readFile(profile, \"utf-8\");\n const params: ProfileParams = YAML.parse(text);\n const store = new SubStore(params);\n return store;\n },\n brief: \"profile\",\n default: \"profile.yaml\",\n },\n template: {\n kind: \"parsed\",\n async parse(template: string): Promise<string> {\n const text: string = await fs.readFile(template, \"utf-8\");\n return text;\n },\n brief: \"template\",\n default: \"templates/mihomo/default.yaml\",\n },\n },\n },\n});\n",
|
|
8
|
+
"import YAML from \"yaml\";\nimport type { Mihomo } from \"./schema\";\n\nexport function parseMihomo(text: string): Mihomo {\n return YAML.parse(text, { merge: true }) as Mihomo;\n}\n",
|
|
9
|
+
"import z from \"zod/v4\";\n\nexport const DEFAULT_URL_TEST = \"https://cp.cloudflare.com\";\n\nexport const PORT_SCHEMA = z.int().min(1).max(65535);\n\nexport const MIHOMO_PROXY_SCHEMA = z.looseObject({\n name: z.string(),\n server: z.string(),\n});\nexport type MihomoProxy = z.infer<typeof MIHOMO_PROXY_SCHEMA>;\n\nexport const MIHOMO_PROXY_GROUP_SCHEMA = z.looseObject({\n name: z.string(),\n type: z.enum([\"select\", \"url-test\"]),\n proxies: z.array(z.string()),\n url: z.url().default(DEFAULT_URL_TEST).optional(),\n interval: z.int().positive().default(300).optional(),\n lazy: z.boolean().default(true).optional(),\n icon: z.string().optional(),\n});\nexport type MihomoProxyGroupOptions = z.input<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\nexport type MihomoProxyGroup = z.infer<typeof MIHOMO_PROXY_GROUP_SCHEMA>;\n\nexport const MIHOMO_SCHEMA = z.looseObject({\n \"mixed-port\": PORT_SCHEMA.default(7892).optional(),\n proxies: z.array(MIHOMO_PROXY_SCHEMA).optional(),\n \"proxy-groups\": z.array(MIHOMO_PROXY_GROUP_SCHEMA).optional(),\n});\nexport type Mihomo = z.infer<typeof MIHOMO_SCHEMA>;\n",
|
|
10
|
+
"import * as R from \"remeda\";\nimport YAML from \"yaml\";\nimport z from \"zod/v4\";\nimport type { Group } from \"../../groups\";\nimport type { Outbound } from \"../../outbound\";\nimport { parseMihomo } from \"./parser\";\nimport {\n MIHOMO_PROXY_GROUP_SCHEMA,\n type Mihomo,\n type MihomoProxy,\n type MihomoProxyGroup,\n type MihomoProxyGroupOptions,\n PORT_SCHEMA,\n} from \"./schema\";\n\nconst MIHOMO_TEMPLATE_OPTIONS_SCHEMA = z.object({\n port: PORT_SCHEMA.default(7890),\n});\n\ntype MihomoTemplateOptions = z.input<typeof MIHOMO_TEMPLATE_OPTIONS_SCHEMA>;\ntype MihomoTemplateOptionsParsed = z.infer<\n typeof MIHOMO_TEMPLATE_OPTIONS_SCHEMA\n>;\n\nexport class MihomoTemplate {\n options: MihomoTemplateOptionsParsed;\n template: Mihomo;\n\n constructor(template: string, options: MihomoTemplateOptions) {\n this.template = parseMihomo(template);\n this.options = MIHOMO_TEMPLATE_OPTIONS_SCHEMA.parse(options);\n }\n\n render(outbounds: Outbound[], groups: Group[]): string {\n let result: Mihomo = R.clone(this.template);\n result.proxies = outbounds\n .map((outbound: Outbound) => outbound.mihomo)\n .filter((mihomo): mihomo is MihomoProxy => mihomo !== undefined);\n const groupDefault: MihomoProxyGroup = this.renderGroupDefault();\n result[\"proxy-groups\"] = [groupDefault];\n for (const group of groups) {\n const proxyGroup: MihomoProxyGroup | undefined = this.renderGroup(\n outbounds,\n group,\n );\n if (!proxyGroup) continue;\n result[\"proxy-groups\"].push(proxyGroup);\n groupDefault.proxies.push(proxyGroup.name);\n }\n result[\"mixed-port\"] = this.options.port;\n result = this.sanitize(result);\n return YAML.stringify(result, { aliasDuplicateObjects: false });\n }\n\n sanitize(mihomo: Mihomo): Mihomo {\n // TODO: remove rules to nonexistent outbound\n mihomo = R.omitBy(mihomo, (_val, key: string) => key.startsWith(\"__\"));\n return mihomo;\n }\n\n protected renderGroupDefault(): 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 protected renderGroup(\n outbounds: Outbound[],\n group: Group,\n ): MihomoProxyGroup | undefined {\n const filtered: Outbound[] = outbounds.filter(group.filter);\n if (filtered.length === 0) return undefined;\n const options: MihomoProxyGroupOptions = {\n name: group.name,\n type: group.type,\n proxies: filtered.map(\n (outbound: Outbound): string => outbound.prettyName,\n ),\n url: group.url,\n icon: group.icon,\n };\n return MIHOMO_PROXY_GROUP_SCHEMA.parse(options);\n }\n}\n",
|
|
11
|
+
"import { Cacheable } from \"@type-cacheable/core\";\nimport { LRUCacheAdapter } from \"@type-cacheable/lru-cache-adapter\";\nimport ky from \"ky\";\nimport { LRUCache } from \"lru-cache\";\nimport * as R from \"remeda\";\nimport z from \"zod/v4\";\nimport type { APIBulkResponse, APIResponse } from \"./schema\";\n\nconst cache = new LRUCache<string, APIResponse>({ max: 1024 });\nconst client: LRUCacheAdapter<APIResponse> = new LRUCacheAdapter(cache);\n\nconst API_OPTIONS_SCHEMA = z.object({\n key: z.string(),\n url: z.url().default(\"https://api.ipapi.is/\"),\n maxBulkSize: z.int().positive().default(100),\n});\n\nexport type APIOptions = z.input<typeof API_OPTIONS_SCHEMA>;\n\nexport class API {\n key: string;\n url: string;\n maxBulkSize: number;\n\n constructor(params: APIOptions) {\n const { key, url, maxBulkSize } = API_OPTIONS_SCHEMA.parse(params);\n this.key = key;\n this.url = url;\n this.maxBulkSize = maxBulkSize;\n }\n\n @Cacheable({\n cacheKey(args: any[], _context?: any): string {\n const ip = args[0] as string;\n return ip;\n },\n client,\n })\n async lookup(ip: string): Promise<APIResponse> {\n const url = new URL(this.url);\n const result = (await ky\n .get(url, {\n searchParams: { q: ip, key: this.key },\n })\n .json()) as APIResponse;\n return result;\n }\n\n async bulk(ips: string[]): Promise<APIBulkResponse> {\n ips = R.unique(ips);\n const cacheResults: Record<string, APIResponse | undefined> =\n Object.fromEntries(\n await Promise.all(\n ips.map(\n async (ip: string): Promise<[string, APIResponse | undefined]> => [\n ip,\n await client.get(ip),\n ],\n ),\n ),\n );\n const ipsToLookup: string[] = ips.filter(\n (ip: string): boolean => !cacheResults[ip],\n );\n const newResults: APIBulkResponse = R.mergeAll(\n await Promise.all(\n R.chunk(ipsToLookup, this.maxBulkSize).map(\n async (chunk: string[]): Promise<APIBulkResponse> =>\n await this._bulk(chunk),\n ),\n ),\n );\n const results: APIBulkResponse = R.merge(cacheResults, newResults);\n return results;\n }\n\n protected async _bulk(ips: string[]): Promise<APIBulkResponse> {\n const results = (await ky\n .post(this.url, { json: { ips, key: this.key } })\n .json()) as APIBulkResponse;\n delete results.total_elapsed_ms;\n await Promise.all(\n Object.entries(results).map(\n async ([ip, value]: [string, APIResponse]): Promise<void> => {\n await client.set(ip, value);\n },\n ),\n );\n return results;\n }\n}\n",
|
|
12
|
+
"import * as R from \"remeda\";\nimport type { Country } from \"world-countries\";\nimport countries from \"world-countries\";\nimport { DNS } from \"../dns\";\nimport { API, type APIOptions } from \"./api\";\nimport type { APIBulkResponse, APIResponse } from \"./schema\";\n\nexport class GeoIP {\n api: API;\n dns: DNS = new DNS();\n countries: Record<string, Country> = Object.fromEntries(\n countries.map((country: Country): [string, Country] => [\n country.cca2,\n country,\n ]),\n );\n\n constructor(options: APIOptions) {\n this.api = new API(options);\n }\n\n async lookup(server: string): Promise<Country | undefined> {\n const ips: string[] = await this.dns.resolveIP(server);\n if (ips.length === 0) return undefined;\n const ip: string = ips[0]!;\n const result: APIResponse = await this.api.lookup(ip);\n return this.countries[result.location.country_code];\n }\n\n async bulk(servers: string[]): Promise<Record<string, Country | undefined>> {\n servers = R.unique(servers);\n const ips: Record<string, string | undefined> = Object.fromEntries(\n await Promise.all(\n servers.map(\n async (server: string): Promise<[string, string | undefined]> => {\n const ips: string[] = await this.dns.resolveIP(server);\n return [server, ips[0]];\n },\n ),\n ),\n );\n const results: APIBulkResponse = await this.api.bulk(\n Object.values(ips).filter(\n (ip: string | undefined): ip is string => ip !== undefined,\n ),\n );\n const countries: Record<string, Country | undefined> = {};\n for (const server of servers) {\n const ip: string | undefined = ips[server];\n if (!ip) {\n countries[server] = undefined;\n continue;\n }\n const cca2: string | undefined = results[ip]?.location?.country_code;\n if (!cca2) {\n countries[server] = undefined;\n continue;\n }\n countries[server] = this.countries[cca2];\n }\n return countries;\n }\n}\n",
|
|
13
|
+
"import dns from \"node:dns\";\nimport { LRUCacheAdapter } from \"@type-cacheable/lru-cache-adapter\";\nimport { LRUCache } from \"lru-cache\";\nimport { z } from \"zod/v4\";\nimport { getLogger } from \"../utils\";\n\nconst logger = getLogger();\n\nconst cache: LRUCache<string, string[]> = new LRUCache({ max: 1024 });\nconst client: LRUCacheAdapter<string[]> = new LRUCacheAdapter(cache);\n\nexport class DNS {\n async resolveIP(server: string): Promise<string[]> {\n if (isIP(server)) return [server];\n const results: string[] = [];\n results.push(...(await this.resolve4(server)));\n results.push(...(await this.resolve6(server)));\n const cnames: string[] = await this.resolveCname(server);\n results.push(\n ...(\n await Promise.all(\n cnames.map(\n async (cname: string): Promise<string[]> =>\n await this.resolveIP(cname),\n ),\n )\n ).flat(),\n );\n return results;\n }\n\n async resolve4(server: string): Promise<string[]> {\n if (isIP(server)) return [server];\n const cacheKey: string = `A:${server}`;\n const cached: string[] | undefined = await client.get(cacheKey);\n if (cached !== undefined) return cached;\n let results: string[] = [];\n try {\n results = await dns.promises.resolve4(server);\n } catch (err) {\n logger.debug(`${err}`);\n }\n await client.set(cacheKey, results);\n return results;\n }\n\n async resolve6(server: string): Promise<string[]> {\n if (isIP(server)) return [server];\n const cacheKey: string = `AAAA:${server}`;\n const cached: string[] | undefined = await client.get(cacheKey);\n if (cached !== undefined) return cached;\n let results: string[] = [];\n try {\n results = await dns.promises.resolve6(server);\n } catch (err) {\n logger.debug(`${err}`);\n }\n await client.set(cacheKey, results);\n return results;\n }\n\n async resolveCname(server: string): Promise<string[]> {\n if (isIP(server)) return [server];\n const cacheKey: string = `CNAME:${server}`;\n const cached: string[] | undefined = await client.get(cacheKey);\n if (cached !== undefined) return cached;\n let results: string[] = [];\n try {\n results = await dns.promises.resolveCname(server);\n } catch (err) {\n logger.debug(`${err}`);\n }\n await client.set(cacheKey, results);\n return results;\n }\n}\n\nfunction isIP(server: string): boolean {\n return (\n z.ipv4().safeParse(server).success || z.ipv6().safeParse(server).success\n );\n}\n",
|
|
14
|
+
"import { type ISettingsParam, Logger } from \"tslog\";\n\nexport function getLogger<LogObj>(\n settings?: ISettingsParam<LogObj>,\n logObj?: LogObj,\n): Logger<LogObj> {\n return new Logger(settings, logObj);\n}\n",
|
|
15
|
+
"import { getLogger } from \"./logging\";\n\nconst logger = getLogger();\n\nexport async function fetchUnsafe(\n url: string | URL,\n init?: RequestInit,\n): Promise<Response> {\n logger.debug(\"fetchUnsafe()\", { url, init });\n init = init ?? { redirect: \"follow\" };\n const response: Response = await fetch(url, init);\n if (response.ok) return response;\n throw new Error(`${url} => ${response}`);\n}\n",
|
|
16
|
+
"import z from \"zod/v4\";\n\nexport const API_RESPONSE_VPN_SCHEMA = z.object({\n service: z.string(),\n url: z.string(),\n type: z.string(),\n last_seen: z.number(),\n last_seen_str: z.string(),\n exit_node_region: z.string(),\n country_code: z.string(),\n city_name: z.string(),\n latitude: z.number(),\n longitude: z.number(),\n});\n\nexport const API_RESPONSE_DATACENTER_SCHEMA = z.object({\n datacenter: z.string(),\n domain: z.string(),\n network: z.string(),\n});\n\nexport const API_RESPONSE_COMPANY_SCHEMA = z.object({\n name: z.string(),\n abuser_score: z.string(),\n domain: z.string(),\n type: z.string(),\n network: z.string(),\n whois: z.string(),\n});\n\nexport const API_RESPONSE_ABUSE_SCHEMA = z.object({\n name: z.string(),\n address: z.string(),\n country: z.string(),\n email: z.string(),\n phone: z.string(),\n});\n\nexport const API_RESPONSE_ASN_SCHEMA = z.object({\n asn: z.number().int(),\n abuser_score: z.string(),\n route: z.string(),\n descr: z.string(),\n country: z.string(),\n active: z.string(),\n org: z.string(),\n domain: z.string(),\n abuse: z.string(),\n type: z.string(),\n created: z.string(),\n updated: z.string(),\n rir: z.string(),\n whois: z.string(),\n});\n\nexport const API_RESPONSE_LOCATION_SCHEMA = z.object({\n is_eu_member: z.boolean(),\n calling_code: z.string(),\n currency_code: z.string(),\n continent: z.string(),\n country: z.string(),\n country_code: z.string(),\n state: z.string(),\n city: z.string(),\n latitude: z.number(),\n longitude: z.number(),\n zip: z.string(),\n timezone: z.string(),\n local_time: z.string(),\n local_time_unix: z.number().int(),\n is_dst: z.boolean(),\n other: z.array(z.any()).optional(),\n});\n\nexport const API_RESPONSE_SCHEMA = z.object({\n ip: z.string(),\n rir: z.string(),\n is_bogon: z.boolean(),\n is_mobile: z.boolean(),\n is_satellite: z.boolean(),\n is_crawler: z.boolean(),\n is_datacenter: z.boolean(),\n is_tor: z.boolean(),\n is_proxy: z.boolean(),\n is_vpn: z.boolean(),\n is_abuser: z.boolean(),\n elapsed_ms: z.number(),\n vpn: API_RESPONSE_VPN_SCHEMA,\n datacenter: API_RESPONSE_DATACENTER_SCHEMA,\n company: API_RESPONSE_COMPANY_SCHEMA,\n asn: API_RESPONSE_ASN_SCHEMA,\n location: API_RESPONSE_LOCATION_SCHEMA,\n});\n\nexport type APIResponse = z.infer<typeof API_RESPONSE_SCHEMA>;\n\nexport const API_BULK_RESPONSE_SCHEMA = z.record(\n z.string(),\n API_RESPONSE_SCHEMA,\n);\n\nexport type APIBulkResponse = z.infer<typeof API_BULK_RESPONSE_SCHEMA>;\n",
|
|
17
|
+
"import type { Country } from \"world-countries\";\nimport countries from \"world-countries\";\nimport type { Outbound } from \"../outbound\";\nimport type { Group } from \"./typed\";\n\nexport function makeCountryGroup(country: Country | undefined): Group {\n const cca2: string = country?.cca2.toLowerCase() ?? \"un\";\n return {\n name: country ? country.name.common : \"Unknown\",\n type: country ? \"url-test\" : \"select\",\n emoji: country ? country.flag : \"🇺🇳\",\n icon: `https://flagcdn.com/256x192/${cca2}.png`,\n filter(outbound: Outbound): boolean {\n if (outbound.emby || outbound.placeholder) return false;\n if (!country) return outbound.country === undefined;\n if (!outbound.country) return false;\n return outbound.country === country.cca2;\n },\n };\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 SELECT: Group = {\n name: \"Select\",\n type: \"select\",\n emoji: \"\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Static.png\",\n filter(_outbound: Outbound): boolean {\n return true;\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 if (outbound.emby || outbound.placeholder) return false;\n return outbound.multiplier <= 2.0;\n },\n};\n\nconst AI_EXCLUDE_REGIONS = new Set([\"CN\", \"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 if (outbound.emby || outbound.placeholder) return false;\n return !!outbound.country && !AI_EXCLUDE_REGIONS.has(outbound.country);\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 if (outbound.emby || outbound.placeholder) return false;\n return 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 if (outbound.emby || outbound.placeholder) return false;\n return outbound.multiplier < 2.0;\n },\n};\n\nexport const INFO: Group = {\n name: \"Info\",\n type: \"select\",\n emoji: \"ℹ️\",\n icon: \"https://cdn.jsdelivr.net/gh/Koolson/Qure/IconSet/Color/Airport.png\",\n filter(outbound: Outbound): boolean {\n return outbound.placeholder;\n },\n};\n\n// region Custom\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.emby && outbound.provider === \"CitrusLab\";\n },\n};\n\n// endregion Custom\n\nexport function defaultGroups(): Group[] {\n return [\n AUTO,\n SELECT,\n INFO,\n AI,\n DOWNLOAD,\n STREAM,\n CITRUSLAB_EMBY,\n ...countries.map(makeCountryGroup),\n ];\n}\n",
|
|
18
|
+
"import type { MihomoProxy } from \"../formats\";\nimport type { Connection } from \"./typed\";\n\nexport type OutboundParams = {\n provider?: string;\n overrides?: OutboundProperties;\n mihomo?: MihomoProxy;\n};\n\ntype OutboundProperties = {\n name?: string;\n country?: string;\n emby?: boolean;\n multiplier?: number;\n};\n\nexport class Outbound {\n provider?: string;\n overrides: OutboundProperties;\n\n connection?: Connection;\n country?: string;\n emby: boolean = false;\n multiplier: number = 1.0;\n placeholder: boolean = false;\n\n private _mihomo?: MihomoProxy;\n\n constructor(params: OutboundParams) {\n this.provider = params.provider;\n this.overrides = params.overrides ?? {};\n this._mihomo = params.mihomo;\n }\n\n get name(): string {\n if (this.provider === \"JMS\") {\n const match = this._mihomo!.name.match(/@(?<name>[\\w-]+)/);\n if (match) {\n const name: string = match.groups?.name ?? this._mihomo!.name;\n return name;\n }\n }\n return this._mihomo!.name;\n }\n\n get prettyName(): string {\n if (this.provider) return `[${this.provider}]${this.name}`;\n return this.name;\n }\n\n get server(): string {\n return this._mihomo!.server;\n }\n\n // region Formats\n\n get mihomo(): MihomoProxy | undefined {\n if (!this._mihomo) return undefined;\n return { ...this._mihomo, name: this.prettyName };\n }\n\n // endregion Formats\n}\n",
|
|
19
|
+
"import { Cacheable } from \"@type-cacheable/core\";\nimport { LRUCacheAdapter } from \"@type-cacheable/lru-cache-adapter\";\nimport { LRUCache } from \"lru-cache\";\nimport type { Logger } from \"tslog\";\nimport type { Country } from \"world-countries\";\nimport countries from \"world-countries\";\nimport type { GeoIP } from \"../../geoip\";\nimport type { Outbound } from \"../../outbound\";\nimport { getLogger } from \"../../utils\";\n\nconst logger: Logger<undefined> = getLogger();\n\nconst cache: LRUCache<string, Country> = new LRUCache({ max: 512 });\nconst client: LRUCacheAdapter<Country> = new LRUCacheAdapter(cache);\n\ntype CountryInferrerOptions = {\n geoip?: GeoIP;\n};\n\nexport class CountryInferrer {\n geoip?: GeoIP;\n\n constructor(options?: CountryInferrerOptions) {\n this.geoip = options?.geoip;\n }\n\n async infer(outbound: Outbound): Promise<Country | undefined> {\n const result: Country | \"Unknown\" = await this._infer(outbound);\n if (result === \"Unknown\") return undefined;\n return result;\n }\n\n prettyCountry(country: Country | undefined): string {\n if (!country) return \"Unknown\";\n return `${country.flag} ${country.name.common} (${country.cca2})`;\n }\n\n // @Cacheable cannot cache undefined, so we use a string literal \"Unknown\" as sentinel\n @Cacheable({ client })\n protected async _infer(outbound: Outbound): Promise<Country | \"Unknown\"> {\n let result: Country | undefined;\n result = await this.inferFromName(outbound.name);\n if (result) return result;\n result = await this.inferFromServer(outbound);\n if (result) return result;\n return \"Unknown\";\n }\n\n protected async inferFromServer(\n outbound: Outbound,\n ): Promise<Country | undefined> {\n if (!outbound.server) return undefined;\n if (!this.geoip) return undefined;\n const result: Country | undefined = await this.geoip.lookup(\n outbound.server,\n );\n logger.debug(\n `Country: ${outbound.name} => ${outbound.server} => ${this.prettyCountry(result)}`,\n );\n if (result?.cca2 === \"CN\") return undefined;\n return result;\n }\n\n protected async inferFromName(name?: string): Promise<Country | undefined> {\n if (!name) return undefined;\n for (const country of countries) {\n if (country.cca2 === \"CN\") continue;\n for (const pattern of patterns(country)) {\n if (name.match(pattern)) {\n logger.debug(\n `Country: ${name} =~ ${pattern} ${this.prettyCountry(country)}`,\n );\n return country;\n }\n }\n }\n }\n}\n\nfunction* patterns(country: Country): Generator<RegExp> {\n for (const pattern of patternsMaybeEmpty(country)) {\n if (!pattern) continue;\n yield pattern;\n }\n}\n\nfunction* patternsMaybeEmpty(country: Country): Generator<RegExp | undefined> {\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 patternShort(display.of(country.cca2));\n } else if (style === \"long\") {\n yield patternLong(display.of(country.cca2));\n }\n }\n }\n yield patternLong(country.name.common);\n yield patternLong(country.name.official);\n for (const lang in country.name.native) {\n yield patternLong(country.name.native[lang]!.common);\n yield patternLong(country.name.native[lang]!.official);\n }\n yield patternShort(country.cca2);\n // yield patternLong(country.ccn3);\n yield patternShort(country.cca3);\n yield patternShort(country.cioc);\n for (const capital of country.capital) yield patternLong(capital);\n // for (const alt of country.altSpellings) yield patternLong(alt);\n}\n\nconst EXCLUDE_PATTERNS = new Set([\"GB\"]);\n\nfunction patternShort(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\nfunction patternLong(pattern?: string): RegExp | undefined {\n if (!pattern) return undefined;\n return new RegExp(pattern, \"i\");\n}\n",
|
|
20
|
+
"import type { Outbound } from \"../../outbound\";\n\nexport class EmbyInferrer {\n infer(outbound: Outbound): boolean {\n return !!outbound.name.match(/emby/i);\n }\n}\n",
|
|
21
|
+
"import type { Outbound } from \"../../outbound\";\n\nexport class MultiplierInferrer {\n infer(outbound: Outbound): number {\n if (outbound.overrides.multiplier !== undefined)\n return outbound.overrides.multiplier;\n const match = outbound.name.match(/(([0-9]*[.])?[0-9]+)x/i);\n if (match) return Number.parseFloat(match[1]!);\n return 1.0;\n }\n}\n",
|
|
22
|
+
"import type { Outbound } from \"../../outbound\";\n\nexport class PlaceholderInferrer {\n infer(outbound: Outbound): boolean {\n if (outbound.name.match(/剩余流量|距离下次重置剩余|套餐到期/i)) return true;\n return false;\n }\n}\n",
|
|
23
|
+
"import z from \"zod/v4\";\nimport { PROVIDER_SCHEMA } from \"../provider\";\n\nexport const PROFILE_SCHEMA = z.object({\n providers: z.array(PROVIDER_SCHEMA),\n});\nexport type ProfileParams = z.input<typeof PROFILE_SCHEMA>;\nexport type ProfileParsed = z.output<typeof PROFILE_SCHEMA>;\n",
|
|
24
|
+
"import { Cacheable } from \"@type-cacheable/core\";\nimport {\n type LRUCacheAdapter,\n useAdapter,\n} from \"@type-cacheable/lru-cache-adapter\";\nimport ky from \"ky\";\nimport { LRUCache } from \"lru-cache\";\nimport z from \"zod/v4\";\n\nconst client: LRUCache<string, any> = new LRUCache({ max: 8 });\nconst adaptor: LRUCacheAdapter<any> = useAdapter(client, undefined, {\n excludeContext: false,\n});\n\nconst SUBCONVERTER_SCHEMA = z.object({\n url: z.url(),\n target: z.string(),\n backend: z.string().default(\"https://url.v1.mk/sub\"),\n});\ntype SubconverterParams = z.input<typeof SUBCONVERTER_SCHEMA>;\n\nexport class Fetcher {\n async subconvert(params: SubconverterParams): Promise<string> {\n const { url: origin, target, backend } = SUBCONVERTER_SCHEMA.parse(params);\n const url = new URL(backend);\n url.searchParams.set(\"url\", origin);\n url.searchParams.set(\"target\", target);\n url.searchParams.set(\"list\", \"true\");\n return await this.fetchText(url);\n }\n\n @Cacheable({ client: adaptor })\n async fetchText(url: string | URL, ua?: string): Promise<string> {\n const headers = new Headers();\n if (ua) headers.set(\"User-Agent\", ua);\n const text: string = await ky.get(url, { headers }).text();\n return text;\n }\n}\n\nexport const fetcher = new Fetcher();\n",
|
|
25
|
+
"import z from \"zod/v4\";\nimport { type Mihomo, type MihomoProxy, parseMihomo } from \"../formats\";\nimport { Outbound } from \"../outbound\";\nimport { fetcher } from \"./fetch\";\n\nexport const PROVIDER_SCHEMA = z.object({\n name: z.string(),\n free: z.boolean().default(false),\n // subscription format\n mihomo: z\n .object({ url: z.url(), ua: z.string().default(\"clash.meta\") })\n .optional(),\n jms: z.object({ api: z.url().optional(), url: z.url() }).optional(),\n});\n\nexport type ProviderParams = z.input<typeof PROVIDER_SCHEMA>;\n\nexport type ProviderParsed = z.infer<typeof PROVIDER_SCHEMA>;\n\nexport class Provider {\n public name: string;\n public free: boolean;\n // subscription format\n public mihomo?: { url: string; ua: string };\n public jms?: { api?: string; url: string };\n\n private _mihomo?: Mihomo;\n\n constructor(params: ProviderParams) {\n const parsed: ProviderParsed = PROVIDER_SCHEMA.parse(params);\n this.name = parsed.name;\n this.free = parsed.free;\n this.mihomo = parsed.mihomo;\n this.jms = parsed.jms;\n }\n\n async fetchMihomo(): Promise<Mihomo> {\n if (!this._mihomo) {\n let text: string = \"\";\n if (this.mihomo) {\n text = await fetcher.fetchText(this.mihomo.url, this.mihomo.ua);\n } else if (this.jms) {\n text = await fetcher.subconvert({ url: this.jms.url, target: \"clash\" });\n }\n this._mihomo = parseMihomo(text);\n }\n return this._mihomo!;\n }\n\n async fetchMihomoOutbounds(): Promise<Outbound[]> {\n const mihomo: Mihomo = await this.fetchMihomo();\n return mihomo.proxies!.map(\n (proxy: MihomoProxy): Outbound =>\n new Outbound({ provider: this.name, mihomo: proxy }),\n );\n }\n}\n",
|
|
26
|
+
"import type { Outbound } from \"../outbound\";\nimport { Provider, type ProviderParams } from \"../provider\";\nimport {\n PROFILE_SCHEMA,\n type ProfileParams,\n type ProfileParsed,\n} from \"./schema\";\n\nexport class SubStore {\n profile: ProfileParsed;\n providers: Provider[];\n\n constructor(profile: ProfileParams) {\n this.profile = PROFILE_SCHEMA.parse(profile);\n this.providers = this.profile.providers.map(\n (provider: ProviderParams): Provider => new Provider(provider),\n );\n }\n\n async fetchMihomoOutbounds(): Promise<Outbound[]> {\n const outbounds: Outbound[] = (\n await Promise.all(\n this.providers.map(\n async (provider: Provider): Promise<Outbound[]> =>\n await provider.fetchMihomoOutbounds(),\n ),\n )\n ).flat();\n return outbounds;\n }\n\n async servers(): Promise<string[]> {\n throw new Error(\"Not Implemented\");\n }\n}\n"
|
|
27
|
+
],
|
|
28
|
+
"mappings": "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",
|
|
29
|
+
"debugId": "E1166A616C5684F264756E2164756E21",
|
|
30
|
+
"names": []
|
|
31
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var i=function(g,b,c,d){var e=arguments.length,a=e<3?b:d===null?d=Object.getOwnPropertyDescriptor(b,c):d,f;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")a=Reflect.decorate(g,b,c,d);else for(var h=g.length-1;h>=0;h--)if(f=g[h])a=(e<3?f(a):e>3?f(b,c,a):f(b,c))||a;return e>3&&a&&Object.defineProperty(b,c,a),a};
|
|
2
|
+
export{i as a};
|
|
3
|
+
|
|
4
|
+
//# debugId=706B36E8EF052ADB64756E2164756E21
|
|
5
|
+
//# sourceMappingURL=chunk-7rje8aby.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { src_default as default };
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liblaf/sub-store",
|
|
3
|
+
"description": "TODO",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./bin/sub-store": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/bin/sub-store.d.ts",
|
|
21
|
+
"default": "./dist/bin/sub-store.js"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"TODO"
|
|
27
|
+
],
|
|
28
|
+
"homepage": "https://github.com/liblaf/sub-store",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/liblaf/sub-store/issues"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"author": {
|
|
34
|
+
"name": "liblaf",
|
|
35
|
+
"url": "https://github.com/liblaf",
|
|
36
|
+
"email": "30631553+liblaf@users.noreply.github.com"
|
|
37
|
+
},
|
|
38
|
+
"bin": {
|
|
39
|
+
"sub-store": "./dist/bin/sub-store.js"
|
|
40
|
+
},
|
|
41
|
+
"repository": "github:liblaf/sub-store",
|
|
42
|
+
"funding": {
|
|
43
|
+
"url": "https://github.com/liblaf/sub-store?sponsor=1",
|
|
44
|
+
"type": "github"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "bunup && prettier --write package.json",
|
|
48
|
+
"lint": "prettier --write . && biome check --write",
|
|
49
|
+
"prepack": "npm run build"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@stricli/auto-complete": "^1.2.0",
|
|
53
|
+
"@stricli/core": "^1.2.0",
|
|
54
|
+
"@type-cacheable/core": "^14.1.0",
|
|
55
|
+
"@type-cacheable/lru-cache-adapter": "^18.0.0",
|
|
56
|
+
"ky": "^1.8.1",
|
|
57
|
+
"lru-cache": "^11.1.0",
|
|
58
|
+
"remeda": "^2.24.0",
|
|
59
|
+
"tslog": "^4.9.3",
|
|
60
|
+
"world-countries": "^5.1.0",
|
|
61
|
+
"yaml": "^2.8.0",
|
|
62
|
+
"zod": "^3.25.71"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@biomejs/biome": "latest",
|
|
66
|
+
"@tsconfig/bun": "latest",
|
|
67
|
+
"@types/bun": "latest",
|
|
68
|
+
"bunup": "latest",
|
|
69
|
+
"prettier": "latest"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"typescript": "latest"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public",
|
|
76
|
+
"registry": "https://registry.npmjs.org/",
|
|
77
|
+
"provenance": true
|
|
78
|
+
},
|
|
79
|
+
"readme": "README.md"
|
|
80
|
+
}
|