UNPKG

@herbertgao/surgio

Version:

Generating rules for Surge, Clash, Quantumult like a PRO

144 lines 6.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const zod_1 = require("zod"); const types_1 = require("../types"); const utils_1 = require("../utils"); const validators_1 = require("../validators"); const Provider_1 = __importDefault(require("./Provider")); class CustomProvider extends Provider_1.default { nodeList; underlyingProxy; constructor(name, config) { super(name, config); const schema = zod_1.z.object({ nodeList: zod_1.z.union([ zod_1.z.array(zod_1.z.any()), zod_1.z.function().args(zod_1.z.any()).returns(zod_1.z.any()), ]), underlyingProxy: zod_1.z.ostring(), }); const result = schema.safeParse(config); // istanbul ignore next if (!result.success) { throw new utils_1.SurgioError('CustomProvider 配置校验失败', { cause: result.error, providerName: name, }); } this.nodeList = result.data.nodeList; this.underlyingProxy = result.data.underlyingProxy; } getNodeList = async (params = {}) => { let nodeList; const parsedNodeList = []; if (typeof this.nodeList === 'function') { nodeList = await this.nodeList(params); } else { nodeList = this.nodeList; } nodeList.forEach((node, index) => { try { const type = node.type; // istanbul ignore next if (node['udp-relay']) { throw new Error('udp-relay 已废弃, 请使用 udpRelay'); } // istanbul ignore next if (node['obfs-host']) { throw new Error('obfs-host 已废弃, 请使用 obfsHost'); } // istanbul ignore next if (node['obfs-uri']) { throw new Error('obfs-uri 已废弃, 请使用 obfsUri'); } // istanbul ignore next let parsedNode = (() => { switch (type) { case types_1.NodeTypeEnum.Shadowsocks: return validators_1.ShadowsocksNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Shadowsocksr: return validators_1.ShadowsocksrNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Vmess: return validators_1.VmessNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Trojan: return validators_1.TrojanNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Socks5: return validators_1.Socks5NodeConfigValidator.parse(node); case types_1.NodeTypeEnum.HTTP: return validators_1.HttpNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.HTTPS: return validators_1.HttpsNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Snell: return validators_1.SnellNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Tuic: return validators_1.TuicNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Wireguard: return validators_1.WireguardNodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Hysteria2: return validators_1.Hysteria2NodeConfigValidator.parse(node); case types_1.NodeTypeEnum.Vless: return validators_1.VlessNodeConfigValidator.parse(node); default: throw new TypeError(`无法识别的节点类型:${type}`); } })(); if (this.underlyingProxy && !parsedNode.underlyingProxy) { parsedNode.underlyingProxy = this.underlyingProxy; } if (parsedNode.type === types_1.NodeTypeEnum.Vmess) { parsedNode = this.prepareVmessNodeConfig(parsedNode); } parsedNodeList.push(parsedNode); } catch (err) { throw new utils_1.SurgioError('节点配置校验失败', { providerName: this.name, nodeIndex: index, cause: err, }); } }); if (this.config.hooks?.afterNodeListResponse) { const newList = await this.config.hooks.afterNodeListResponse(parsedNodeList, params); if (newList) { return newList; } } return parsedNodeList; }; prepareVmessNodeConfig(node) { if (node.host) { node.sni = node.host; } if (node.wsHeaders) { if (!node.wsOpts) { node.wsOpts = { headers: node.wsHeaders, path: node.path || '/', }; } else if (node.wsOpts.headers) { throw new Error('wsOpts.headers 和 wsHeaders 不能同时存在'); } else { node.wsOpts.headers = node.wsHeaders; } } if (node.network === 'ws' && node.path) { throw new Error('请将 path 移动到 wsOpts.path'); } if (node.network === 'h2' && node.path) { throw new Error('请将 path 移动到 h2Opts.path'); } if (node.network === 'http' && node.path) { throw new Error('请将 path 移动到 httpOpts.path'); } return node; } } exports.default = CustomProvider; //# sourceMappingURL=CustomProvider.js.map