fix: support esm socks-proxy-agent in niupanel

This commit is contained in:
2026-06-07 14:27:14 +08:00
parent 9d899f7a5a
commit aa40805859
+27 -11
View File
@@ -5,10 +5,27 @@ const vm = require('vm');
const { AsyncLocalStorage } = require('async_hooks'); const { AsyncLocalStorage } = require('async_hooks');
let SocksProxyAgent = null; let SocksProxyAgent = null;
let socksProxyAgentImportPromise = null;
try { try {
({ SocksProxyAgent } = require('socks-proxy-agent')); ({ SocksProxyAgent } = require('socks-proxy-agent'));
} catch (e) { } catch (e) {
// 未配置代理时不需要安装;配置 SOCKS5 代理时会给出明确提示 // socks-proxy-agent v8+ 是 ESMCommonJS require 会失败;真正配置代理时再用 dynamic import 加载
}
async function loadSocksProxyAgent() {
if (SocksProxyAgent) return SocksProxyAgent;
if (!socksProxyAgentImportPromise) {
socksProxyAgentImportPromise = import('socks-proxy-agent')
.then(mod => {
SocksProxyAgent = mod.SocksProxyAgent;
return SocksProxyAgent;
})
.catch(err => {
socksProxyAgentImportPromise = null;
throw err;
});
}
return socksProxyAgentImportPromise;
} }
// ============================================ // ============================================
@@ -74,7 +91,6 @@ const AXIOS_COMMON_OPTS = {
// ========== 账号级 SOCKS5 代理 ========== // ========== 账号级 SOCKS5 代理 ==========
const accountContext = new AsyncLocalStorage(); const accountContext = new AsyncLocalStorage();
const socksAgentCache = new Map(); const socksAgentCache = new Map();
const axiosRequestRaw = axios.request.bind(axios);
function normalizeSocksProxy(proxyUrl) { function normalizeSocksProxy(proxyUrl) {
const raw = String(proxyUrl || '').trim(); const raw = String(proxyUrl || '').trim();
@@ -99,24 +115,27 @@ function maskProxyUrl(proxyUrl) {
} }
} }
function getSocksAgent(proxyUrl) { async function getSocksAgent(proxyUrl) {
const normalized = normalizeSocksProxy(proxyUrl); const normalized = normalizeSocksProxy(proxyUrl);
if (!normalized) return null; if (!normalized) return null;
if (!SocksProxyAgent) { const AgentCtor = await loadSocksProxyAgent().catch(err => {
throw new Error('已配置SOCKS5代理,但缺少依赖 socks-proxy-agent,请先执行: npm install'); throw new Error(`已配置SOCKS5代理,但加载依赖 socks-proxy-agent 失败,请先在脚本目录执行 npm install socks-proxy-agent。原始错误: ${err.message}`);
});
if (!AgentCtor) {
throw new Error('已配置SOCKS5代理,但缺少依赖 socks-proxy-agent,请先在脚本目录执行: npm install socks-proxy-agent');
} }
if (!socksAgentCache.has(normalized)) { if (!socksAgentCache.has(normalized)) {
socksAgentCache.set(normalized, new SocksProxyAgent(normalized)); socksAgentCache.set(normalized, new AgentCtor(normalized));
} }
return socksAgentCache.get(normalized); return socksAgentCache.get(normalized);
} }
function applyCurrentAccountProxy(config = {}) { async function applyCurrentAccountProxy(config = {}) {
const ctx = accountContext.getStore(); const ctx = accountContext.getStore();
const proxyUrl = ctx && ctx.socksProxy; const proxyUrl = ctx && ctx.socksProxy;
if (!proxyUrl) return config; if (!proxyUrl) return config;
const agent = getSocksAgent(proxyUrl); const agent = await getSocksAgent(proxyUrl);
return { return {
...config, ...config,
proxy: false, proxy: false,
@@ -125,9 +144,6 @@ function applyCurrentAccountProxy(config = {}) {
}; };
} }
axios.request = function patchedAxiosRequest(config) {
return axiosRequestRaw(applyCurrentAccountProxy(config || {}));
};
axios.interceptors.request.use(config => applyCurrentAccountProxy(config || {})); axios.interceptors.request.use(config => applyCurrentAccountProxy(config || {}));
function runWithAccountProxy(socksProxy, fn) { function runWithAccountProxy(socksProxy, fn) {