feat: 订阅和文件的请求链接支持传入 $options , 可在脚本中使用

This commit is contained in:
xream
2024-09-03 13:58:10 +08:00
parent e1489a3cf7
commit 99d5868cff
7 changed files with 103 additions and 12 deletions

View File

@@ -77,7 +77,13 @@ function parse(raw) {
return proxies;
}
async function processFn(proxies, operators = [], targetPlatform, source) {
async function processFn(
proxies,
operators = [],
targetPlatform,
source,
$options,
) {
for (const item of operators) {
// process script
let script;
@@ -176,6 +182,7 @@ async function processFn(proxies, operators = [], targetPlatform, source) {
targetPlatform,
$arguments,
source,
$options,
);
} else {
processor = PROXY_PROCESSORS[item.type](item.args || {});

View File

@@ -316,7 +316,7 @@ function RegexDeleteOperator(regex) {
1. This function name should be `operator`!
2. Always declare variables before using them!
*/
function ScriptOperator(script, targetPlatform, $arguments, source) {
function ScriptOperator(script, targetPlatform, $arguments, source, $options) {
return {
name: 'Script Operator',
func: async (proxies) => {
@@ -326,6 +326,7 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
'operator',
script,
$arguments,
$options,
);
output = operator(proxies, targetPlatform, { source, ...env });
})();
@@ -338,9 +339,9 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
'operator',
`async function operator(input = []) {
if (input && (input.$files || input.$content)) {
let { $content, $files } = input
let { $content, $files, $options } = input
${script}
return { $content, $files }
return { $content, $files, $options }
} else {
let proxies = input
let list = []
@@ -352,6 +353,7 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
}
}`,
$arguments,
$options,
);
output = operator(proxies, targetPlatform, { source, ...env });
})();
@@ -794,7 +796,7 @@ function TypeFilter(types) {
1. This function name should be `filter`!
2. Always declare variables before using them!
*/
function ScriptFilter(script, targetPlatform, $arguments, source) {
function ScriptFilter(script, targetPlatform, $arguments, source, $options) {
return {
name: 'Script Filter',
func: async (proxies) => {
@@ -804,6 +806,7 @@ function ScriptFilter(script, targetPlatform, $arguments, source) {
'filter',
script,
$arguments,
$options,
);
output = filter(proxies, targetPlatform, { source, ...env });
})();
@@ -826,6 +829,7 @@ function ScriptFilter(script, targetPlatform, $arguments, source) {
return list
}`,
$arguments,
$options,
);
output = filter(proxies, targetPlatform, { source, ...env });
})();
@@ -966,7 +970,7 @@ function clone(object) {
return JSON.parse(JSON.stringify(object));
}
function createDynamicFunction(name, script, $arguments) {
function createDynamicFunction(name, script, $arguments, $options) {
const flowUtils = {
getFlowField,
getFlowHeaders,
@@ -978,6 +982,7 @@ function createDynamicFunction(name, script, $arguments) {
if ($.env.isLoon) {
return new Function(
'$arguments',
'$options',
'$substore',
'lodash',
'$persistentStore',
@@ -991,6 +996,7 @@ function createDynamicFunction(name, script, $arguments) {
`${script}\n return ${name}`,
)(
$arguments,
$options,
$,
lodash,
// eslint-disable-next-line no-undef
@@ -1008,6 +1014,7 @@ function createDynamicFunction(name, script, $arguments) {
} else {
return new Function(
'$arguments',
'$options',
'$substore',
'lodash',
'ProxyUtils',
@@ -1018,6 +1025,7 @@ function createDynamicFunction(name, script, $arguments) {
`${script}\n return ${name}`,
)(
$arguments,
$options,
$,
lodash,
ProxyUtils,

View File

@@ -70,6 +70,24 @@ async function downloadSubscription(req, res) {
includeUnsupportedProxy,
resultFormat,
} = req.query;
let $options = {};
if (req.query.$options) {
try {
// 支持 `#${encodeURIComponent(JSON.stringify({arg1: "1"}))}`
$options = JSON.parse(decodeURIComponent(req.query.$options));
} catch (e) {
for (const pair of req.query.$options.split('&')) {
const key = pair.split('=')[0];
const value = pair.split('=')[1];
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
$options[key] =
value == null || value === ''
? true
: decodeURIComponent(value);
}
}
$.info(`传入 $options: ${JSON.stringify($options)}`);
}
if (url) {
url = decodeURIComponent(url);
$.info(`指定远程订阅 URL: ${url}`);
@@ -116,6 +134,7 @@ async function downloadSubscription(req, res) {
produceOpts: {
'include-unsupported-proxy': includeUnsupportedProxy,
},
$options,
});
if (
@@ -247,6 +266,25 @@ async function downloadCollection(req, res) {
resultFormat,
} = req.query;
let $options = {};
if (req.query.$options) {
try {
// 支持 `#${encodeURIComponent(JSON.stringify({arg1: "1"}))}`
$options = JSON.parse(decodeURIComponent(req.query.$options));
} catch (e) {
for (const pair of req.query.$options.split('&')) {
const key = pair.split('=')[0];
const value = pair.split('=')[1];
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
$options[key] =
value == null || value === ''
? true
: decodeURIComponent(value);
}
}
$.info(`传入 $options: ${JSON.stringify($options)}`);
}
if (ignoreFailedRemoteSub != null && ignoreFailedRemoteSub !== '') {
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
@@ -272,6 +310,7 @@ async function downloadCollection(req, res) {
produceOpts: {
'include-unsupported-proxy': includeUnsupportedProxy,
},
$options,
});
// forward flow header from the first subscription in this collection

View File

@@ -60,6 +60,24 @@ async function getFile(req, res) {
mergeSources,
ignoreFailedRemoteFile,
} = req.query;
let $options = {};
if (req.query.$options) {
try {
// 支持 `#${encodeURIComponent(JSON.stringify({arg1: "1"}))}`
$options = JSON.parse(decodeURIComponent(req.query.$options));
} catch (e) {
for (const pair of req.query.$options.split('&')) {
const key = pair.split('=')[0];
const value = pair.split('=')[1];
// 部分兼容之前的逻辑 const value = pair.split('=')[1] || true;
$options[key] =
value == null || value === ''
? true
: decodeURIComponent(value);
}
}
$.info(`传入 $options: ${JSON.stringify($options)}`);
}
if (url) {
url = decodeURIComponent(url);
$.info(`指定远程文件 URL: ${url}`);
@@ -101,6 +119,7 @@ async function getFile(req, res) {
content,
mergeSources,
ignoreFailedRemoteFile,
$options,
});
try {

View File

@@ -37,6 +37,7 @@ async function produceArtifact({
produceOpts = {},
subscription,
awaitCustomCache,
$options,
}) {
platform = platform || 'JSON';
@@ -158,6 +159,7 @@ async function produceArtifact({
sub.process || [],
platform,
{ [sub.name]: sub },
$options,
);
if (proxies.length === 0) {
throw new Error(`订阅 ${name} 中不含有效节点`);
@@ -259,7 +261,11 @@ async function produceArtifact({
currentProxies,
sub.process || [],
platform,
{ [sub.name]: sub, _collection: collection },
{
[sub.name]: sub,
_collection: collection,
$options,
},
);
results[name] = currentProxies;
processed++;
@@ -312,6 +318,7 @@ async function produceArtifact({
collection.process || [],
platform,
{ _collection: collection },
$options,
);
if (proxies.length === 0) {
throw new Error(`组合订阅 ${name} 中不含有效节点`);
@@ -460,10 +467,10 @@ async function produceArtifact({
const processed =
Array.isArray(file.process) && file.process.length > 0
? await ProxyUtils.process(
{ $files: files, $content: filesContent },
{ $files: files, $content: filesContent, $options },
file.process,
)
: { $content: filesContent, $files: files };
: { $content: filesContent, $files: files, $options };
return processed?.$content ?? '';
}