feat: 脚本内部 produceArtifact 支持指定 produceType: 'internal', produceOpts: { 'include-unsupported-proxy': true } 来获得内部的数据结构; 订阅链接参数支持 type=internal&includeUnsupportedProxy=true; 文件支持 nunjucks 模板, 为 sing-box 增加的 Filter 用法 sub/col 为订阅/组合订阅中的节点名 {{ '订阅的name' | sub('美国|🇺🇸|us', 'i') }}, subNode/colNode 为订阅/组合订阅中的节点 {{ '订阅的name' | subNode('美国|🇺🇸|us', 'i') }}, 底层 produceArtifact('subscription', 'sing-box', 'internal', '美国|🇺🇸|us', 'i')

This commit is contained in:
xream
2024-01-14 12:13:29 +08:00
parent 12903d77f7
commit 5ecce27f4e
12 changed files with 586 additions and 286 deletions

View File

@@ -20,7 +20,15 @@ async function downloadSubscription(req, res) {
req.query.target || getPlatformFromHeaders(req.headers) || 'JSON';
$.info(`正在下载订阅:${name}`);
let { url, ua, content, mergeSources, ignoreFailedRemoteSub } = req.query;
let {
url,
ua,
content,
mergeSources,
ignoreFailedRemoteSub,
produceType,
includeUnsupportedProxy,
} = req.query;
if (url) {
url = decodeURIComponent(url);
$.info(`指定远程订阅 URL: ${url}`);
@@ -41,6 +49,14 @@ async function downloadSubscription(req, res) {
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
}
if (produceType) {
produceType = decodeURIComponent(produceType);
$.info(`指定生产类型: ${produceType}`);
}
if (includeUnsupportedProxy) {
includeUnsupportedProxy = decodeURIComponent(includeUnsupportedProxy);
$.info(`包含不支持的节点: ${includeUnsupportedProxy}`);
}
const allSubs = $.read(SUBS_KEY);
const sub = findByName(allSubs, name);
@@ -55,6 +71,10 @@ async function downloadSubscription(req, res) {
content,
mergeSources,
ignoreFailedRemoteSub,
produceType,
produceOpts: {
'include-unsupported-proxy': includeUnsupportedProxy,
},
});
if (sub.source !== 'local' || url) {
@@ -121,12 +141,22 @@ async function downloadCollection(req, res) {
$.info(`正在下载组合订阅:${name}`);
let { ignoreFailedRemoteSub } = req.query;
let { ignoreFailedRemoteSub, produceType, includeUnsupportedProxy } =
req.query;
if (ignoreFailedRemoteSub != null && ignoreFailedRemoteSub !== '') {
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
}
if (produceType) {
produceType = decodeURIComponent(produceType);
$.info(`指定生产类型: ${produceType}`);
}
if (includeUnsupportedProxy) {
includeUnsupportedProxy = decodeURIComponent(includeUnsupportedProxy);
$.info(`包含不支持的节点: ${includeUnsupportedProxy}`);
}
if (collection) {
try {
@@ -135,6 +165,10 @@ async function downloadCollection(req, res) {
name,
platform,
ignoreFailedRemoteSub,
produceType,
produceOpts: {
'include-unsupported-proxy': includeUnsupportedProxy,
},
});
// forward flow header from the first subscription in this collection

View File

@@ -3,6 +3,7 @@ import { ProxyUtils } from '@/core/proxy-utils';
import { findByName } from '@/utils/database';
import { success, failed } from './response';
import download from '@/utils/download';
import { render } from '@/utils/tpl';
import { SUBS_KEY } from '@/constants';
import $ from '@/core/app';
@@ -59,10 +60,14 @@ async function previewFile(req, res) {
}
// parse proxies
const files = (Array.isArray(content) ? content : [content]).flat();
const filesContent = files
let filesContent = files
.filter((i) => i != null && i !== '')
.join('\n');
if (file.isTpl) {
filesContent = await render(filesContent);
}
// apply processors
const processed =
Array.isArray(file.process) && file.process.length > 0

View File

@@ -13,6 +13,7 @@ import download from '@/utils/download';
import { ProxyUtils } from '@/core/proxy-utils';
import { RuleUtils } from '@/core/rule-utils';
import { syncToGist } from '@/restful/artifacts';
import { render } from '@/utils/tpl';
export default function register($app) {
// Initialization
@@ -33,6 +34,8 @@ async function produceArtifact({
mergeSources,
ignoreFailedRemoteSub,
ignoreFailedRemoteFile,
produceType,
produceOpts = {},
}) {
platform = platform || 'JSON';
@@ -154,7 +157,7 @@ async function produceArtifact({
exist[proxy.name] = true;
}
// produce
return ProxyUtils.produce(proxies, platform);
return ProxyUtils.produce(proxies, platform, produceType, produceOpts);
} else if (type === 'collection') {
const allSubs = $.read(SUBS_KEY);
const allCols = $.read(COLLECTIONS_KEY);
@@ -301,7 +304,7 @@ async function produceArtifact({
}
exist[proxy.name] = true;
}
return ProxyUtils.produce(proxies, platform);
return ProxyUtils.produce(proxies, platform, produceType, produceOpts);
} else if (type === 'rule') {
const allRules = $.read(RULES_KEY);
const rule = findByName(allRules, name);
@@ -419,10 +422,13 @@ async function produceArtifact({
}
}
const files = (Array.isArray(raw) ? raw : [raw]).flat();
const filesContent = files
let filesContent = files
.filter((i) => i != null && i !== '')
.join('\n');
if (file.isTpl) {
filesContent = await render(filesContent);
}
// apply processors
const processed =
Array.isArray(file.process) && file.process.length > 0