@herbertgao/surgio
Version:
Generating rules for Surge, Clash, Quantumult like a PRO
144 lines • 6.18 kB
JavaScript
;
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