mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-09-17 01:53:12 +08:00
feat: 订阅和文件的请求链接支持传入 $options
, 可在脚本中使用
This commit is contained in:
parent
e1489a3cf7
commit
99d5868cff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.14.372",
|
"version": "2.14.373",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -77,7 +77,13 @@ function parse(raw) {
|
|||||||
return proxies;
|
return proxies;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processFn(proxies, operators = [], targetPlatform, source) {
|
async function processFn(
|
||||||
|
proxies,
|
||||||
|
operators = [],
|
||||||
|
targetPlatform,
|
||||||
|
source,
|
||||||
|
$options,
|
||||||
|
) {
|
||||||
for (const item of operators) {
|
for (const item of operators) {
|
||||||
// process script
|
// process script
|
||||||
let script;
|
let script;
|
||||||
@ -176,6 +182,7 @@ async function processFn(proxies, operators = [], targetPlatform, source) {
|
|||||||
targetPlatform,
|
targetPlatform,
|
||||||
$arguments,
|
$arguments,
|
||||||
source,
|
source,
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
processor = PROXY_PROCESSORS[item.type](item.args || {});
|
processor = PROXY_PROCESSORS[item.type](item.args || {});
|
||||||
|
@ -316,7 +316,7 @@ function RegexDeleteOperator(regex) {
|
|||||||
1. This function name should be `operator`!
|
1. This function name should be `operator`!
|
||||||
2. Always declare variables before using them!
|
2. Always declare variables before using them!
|
||||||
*/
|
*/
|
||||||
function ScriptOperator(script, targetPlatform, $arguments, source) {
|
function ScriptOperator(script, targetPlatform, $arguments, source, $options) {
|
||||||
return {
|
return {
|
||||||
name: 'Script Operator',
|
name: 'Script Operator',
|
||||||
func: async (proxies) => {
|
func: async (proxies) => {
|
||||||
@ -326,6 +326,7 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
|
|||||||
'operator',
|
'operator',
|
||||||
script,
|
script,
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
output = operator(proxies, targetPlatform, { source, ...env });
|
output = operator(proxies, targetPlatform, { source, ...env });
|
||||||
})();
|
})();
|
||||||
@ -338,9 +339,9 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
|
|||||||
'operator',
|
'operator',
|
||||||
`async function operator(input = []) {
|
`async function operator(input = []) {
|
||||||
if (input && (input.$files || input.$content)) {
|
if (input && (input.$files || input.$content)) {
|
||||||
let { $content, $files } = input
|
let { $content, $files, $options } = input
|
||||||
${script}
|
${script}
|
||||||
return { $content, $files }
|
return { $content, $files, $options }
|
||||||
} else {
|
} else {
|
||||||
let proxies = input
|
let proxies = input
|
||||||
let list = []
|
let list = []
|
||||||
@ -352,6 +353,7 @@ function ScriptOperator(script, targetPlatform, $arguments, source) {
|
|||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
output = operator(proxies, targetPlatform, { source, ...env });
|
output = operator(proxies, targetPlatform, { source, ...env });
|
||||||
})();
|
})();
|
||||||
@ -794,7 +796,7 @@ function TypeFilter(types) {
|
|||||||
1. This function name should be `filter`!
|
1. This function name should be `filter`!
|
||||||
2. Always declare variables before using them!
|
2. Always declare variables before using them!
|
||||||
*/
|
*/
|
||||||
function ScriptFilter(script, targetPlatform, $arguments, source) {
|
function ScriptFilter(script, targetPlatform, $arguments, source, $options) {
|
||||||
return {
|
return {
|
||||||
name: 'Script Filter',
|
name: 'Script Filter',
|
||||||
func: async (proxies) => {
|
func: async (proxies) => {
|
||||||
@ -804,6 +806,7 @@ function ScriptFilter(script, targetPlatform, $arguments, source) {
|
|||||||
'filter',
|
'filter',
|
||||||
script,
|
script,
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
output = filter(proxies, targetPlatform, { source, ...env });
|
output = filter(proxies, targetPlatform, { source, ...env });
|
||||||
})();
|
})();
|
||||||
@ -826,6 +829,7 @@ function ScriptFilter(script, targetPlatform, $arguments, source) {
|
|||||||
return list
|
return list
|
||||||
}`,
|
}`,
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
output = filter(proxies, targetPlatform, { source, ...env });
|
output = filter(proxies, targetPlatform, { source, ...env });
|
||||||
})();
|
})();
|
||||||
@ -966,7 +970,7 @@ function clone(object) {
|
|||||||
return JSON.parse(JSON.stringify(object));
|
return JSON.parse(JSON.stringify(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDynamicFunction(name, script, $arguments) {
|
function createDynamicFunction(name, script, $arguments, $options) {
|
||||||
const flowUtils = {
|
const flowUtils = {
|
||||||
getFlowField,
|
getFlowField,
|
||||||
getFlowHeaders,
|
getFlowHeaders,
|
||||||
@ -978,6 +982,7 @@ function createDynamicFunction(name, script, $arguments) {
|
|||||||
if ($.env.isLoon) {
|
if ($.env.isLoon) {
|
||||||
return new Function(
|
return new Function(
|
||||||
'$arguments',
|
'$arguments',
|
||||||
|
'$options',
|
||||||
'$substore',
|
'$substore',
|
||||||
'lodash',
|
'lodash',
|
||||||
'$persistentStore',
|
'$persistentStore',
|
||||||
@ -991,6 +996,7 @@ function createDynamicFunction(name, script, $arguments) {
|
|||||||
`${script}\n return ${name}`,
|
`${script}\n return ${name}`,
|
||||||
)(
|
)(
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
$,
|
$,
|
||||||
lodash,
|
lodash,
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
@ -1008,6 +1014,7 @@ function createDynamicFunction(name, script, $arguments) {
|
|||||||
} else {
|
} else {
|
||||||
return new Function(
|
return new Function(
|
||||||
'$arguments',
|
'$arguments',
|
||||||
|
'$options',
|
||||||
'$substore',
|
'$substore',
|
||||||
'lodash',
|
'lodash',
|
||||||
'ProxyUtils',
|
'ProxyUtils',
|
||||||
@ -1018,6 +1025,7 @@ function createDynamicFunction(name, script, $arguments) {
|
|||||||
`${script}\n return ${name}`,
|
`${script}\n return ${name}`,
|
||||||
)(
|
)(
|
||||||
$arguments,
|
$arguments,
|
||||||
|
$options,
|
||||||
$,
|
$,
|
||||||
lodash,
|
lodash,
|
||||||
ProxyUtils,
|
ProxyUtils,
|
||||||
|
@ -70,6 +70,24 @@ async function downloadSubscription(req, res) {
|
|||||||
includeUnsupportedProxy,
|
includeUnsupportedProxy,
|
||||||
resultFormat,
|
resultFormat,
|
||||||
} = req.query;
|
} = 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) {
|
if (url) {
|
||||||
url = decodeURIComponent(url);
|
url = decodeURIComponent(url);
|
||||||
$.info(`指定远程订阅 URL: ${url}`);
|
$.info(`指定远程订阅 URL: ${url}`);
|
||||||
@ -116,6 +134,7 @@ async function downloadSubscription(req, res) {
|
|||||||
produceOpts: {
|
produceOpts: {
|
||||||
'include-unsupported-proxy': includeUnsupportedProxy,
|
'include-unsupported-proxy': includeUnsupportedProxy,
|
||||||
},
|
},
|
||||||
|
$options,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -247,6 +266,25 @@ async function downloadCollection(req, res) {
|
|||||||
resultFormat,
|
resultFormat,
|
||||||
} = req.query;
|
} = 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 !== '') {
|
if (ignoreFailedRemoteSub != null && ignoreFailedRemoteSub !== '') {
|
||||||
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
|
ignoreFailedRemoteSub = decodeURIComponent(ignoreFailedRemoteSub);
|
||||||
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
|
$.info(`指定忽略失败的远程订阅: ${ignoreFailedRemoteSub}`);
|
||||||
@ -272,6 +310,7 @@ async function downloadCollection(req, res) {
|
|||||||
produceOpts: {
|
produceOpts: {
|
||||||
'include-unsupported-proxy': includeUnsupportedProxy,
|
'include-unsupported-proxy': includeUnsupportedProxy,
|
||||||
},
|
},
|
||||||
|
$options,
|
||||||
});
|
});
|
||||||
|
|
||||||
// forward flow header from the first subscription in this collection
|
// forward flow header from the first subscription in this collection
|
||||||
|
@ -60,6 +60,24 @@ async function getFile(req, res) {
|
|||||||
mergeSources,
|
mergeSources,
|
||||||
ignoreFailedRemoteFile,
|
ignoreFailedRemoteFile,
|
||||||
} = req.query;
|
} = 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) {
|
if (url) {
|
||||||
url = decodeURIComponent(url);
|
url = decodeURIComponent(url);
|
||||||
$.info(`指定远程文件 URL: ${url}`);
|
$.info(`指定远程文件 URL: ${url}`);
|
||||||
@ -101,6 +119,7 @@ async function getFile(req, res) {
|
|||||||
content,
|
content,
|
||||||
mergeSources,
|
mergeSources,
|
||||||
ignoreFailedRemoteFile,
|
ignoreFailedRemoteFile,
|
||||||
|
$options,
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -37,6 +37,7 @@ async function produceArtifact({
|
|||||||
produceOpts = {},
|
produceOpts = {},
|
||||||
subscription,
|
subscription,
|
||||||
awaitCustomCache,
|
awaitCustomCache,
|
||||||
|
$options,
|
||||||
}) {
|
}) {
|
||||||
platform = platform || 'JSON';
|
platform = platform || 'JSON';
|
||||||
|
|
||||||
@ -158,6 +159,7 @@ async function produceArtifact({
|
|||||||
sub.process || [],
|
sub.process || [],
|
||||||
platform,
|
platform,
|
||||||
{ [sub.name]: sub },
|
{ [sub.name]: sub },
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
if (proxies.length === 0) {
|
if (proxies.length === 0) {
|
||||||
throw new Error(`订阅 ${name} 中不含有效节点`);
|
throw new Error(`订阅 ${name} 中不含有效节点`);
|
||||||
@ -259,7 +261,11 @@ async function produceArtifact({
|
|||||||
currentProxies,
|
currentProxies,
|
||||||
sub.process || [],
|
sub.process || [],
|
||||||
platform,
|
platform,
|
||||||
{ [sub.name]: sub, _collection: collection },
|
{
|
||||||
|
[sub.name]: sub,
|
||||||
|
_collection: collection,
|
||||||
|
$options,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
results[name] = currentProxies;
|
results[name] = currentProxies;
|
||||||
processed++;
|
processed++;
|
||||||
@ -312,6 +318,7 @@ async function produceArtifact({
|
|||||||
collection.process || [],
|
collection.process || [],
|
||||||
platform,
|
platform,
|
||||||
{ _collection: collection },
|
{ _collection: collection },
|
||||||
|
$options,
|
||||||
);
|
);
|
||||||
if (proxies.length === 0) {
|
if (proxies.length === 0) {
|
||||||
throw new Error(`组合订阅 ${name} 中不含有效节点`);
|
throw new Error(`组合订阅 ${name} 中不含有效节点`);
|
||||||
@ -460,10 +467,10 @@ async function produceArtifact({
|
|||||||
const processed =
|
const processed =
|
||||||
Array.isArray(file.process) && file.process.length > 0
|
Array.isArray(file.process) && file.process.length > 0
|
||||||
? await ProxyUtils.process(
|
? await ProxyUtils.process(
|
||||||
{ $files: files, $content: filesContent },
|
{ $files: files, $content: filesContent, $options },
|
||||||
file.process,
|
file.process,
|
||||||
)
|
)
|
||||||
: { $content: filesContent, $files: files };
|
: { $content: filesContent, $files: files, $options };
|
||||||
|
|
||||||
return processed?.$content ?? '';
|
return processed?.$content ?? '';
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,17 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
|
|
||||||
// $arguments 为传入的脚本参数
|
// $arguments 为传入的脚本参数
|
||||||
|
|
||||||
|
// $options 为通过链接传入的参数
|
||||||
|
// 例如: { arg1: 'a', arg2: 'b' }
|
||||||
|
// 可这样传:
|
||||||
|
// 先这样处理 encodeURIComponent(JSON.stringify({ arg1: 'a', arg2: 'b' }))
|
||||||
|
// /api/file/foo?$options=%7B%22arg1%22%3A%22a%22%2C%22arg2%22%3A%22b%22%7D
|
||||||
|
// 或这样传:
|
||||||
|
// 先这样处理 encodeURIComponent('arg1=a&arg2=b')
|
||||||
|
// /api/file/foo?$options=arg1%3Da%26arg2%3Db
|
||||||
|
|
||||||
|
// console.log($options)
|
||||||
|
|
||||||
// targetPlatform 为输出的目标平台
|
// targetPlatform 为输出的目标平台
|
||||||
|
|
||||||
// lodash
|
// lodash
|
||||||
@ -133,7 +144,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// yaml.proxies.unshift(...clashMetaProxies)
|
// yaml.proxies.unshift(...clashMetaProxies)
|
||||||
// $content = ProxyUtils.yaml.dump(yaml)
|
// $content = ProxyUtils.yaml.dump(yaml)
|
||||||
|
|
||||||
// { $content, $files } will be passed to the next operator
|
// { $content, $files, $options } will be passed to the next operator
|
||||||
// $content is the final content of the file
|
// $content is the final content of the file
|
||||||
|
|
||||||
// flowUtils 为机场订阅流量信息处理工具
|
// flowUtils 为机场订阅流量信息处理工具
|
||||||
@ -141,7 +152,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// 1. https://t.me/zhetengsha/948
|
// 1. https://t.me/zhetengsha/948
|
||||||
|
|
||||||
// context 为传入的上下文
|
// context 为传入的上下文
|
||||||
// 有三种情况, 按需判断
|
// 其中 source 为 订阅和组合订阅的数据, 有三种情况, 按需判断
|
||||||
|
|
||||||
// 若存在 `source._collection` 且 `source._collection.subscriptions` 中的 key 在 `source` 上也存在, 说明输出结果为组合订阅, 但是脚本设置在单条订阅上
|
// 若存在 `source._collection` 且 `source._collection.subscriptions` 中的 key 在 `source` 上也存在, 说明输出结果为组合订阅, 但是脚本设置在单条订阅上
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user