mirror of
https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-10 00:52:40 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89dbe9ad3d | ||
|
|
56870bbd5f | ||
|
|
efbc6ecd84 | ||
|
|
c27c589024 | ||
|
|
0efed4f1a0 | ||
|
|
e3a514d1fb | ||
|
|
64478c7a27 | ||
|
|
dc8f19f350 | ||
|
|
b4ccfc7e07 | ||
|
|
3f1940630a | ||
|
|
5a0bdb1276 | ||
|
|
a1b86e26a2 | ||
|
|
6ec8c29f6a |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.14.256",
|
"version": "2.14.269",
|
||||||
"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": {
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ async function processFn(proxies, operators = [], targetPlatform, source) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.info(
|
$.log(
|
||||||
`Applying "${item.type}" with arguments:\n >>> ${
|
`Applying "${item.type}" with arguments:\n >>> ${
|
||||||
JSON.stringify(item.args, null, 2) || 'None'
|
JSON.stringify(item.args, null, 2) || 'None'
|
||||||
}`,
|
}`,
|
||||||
@@ -186,6 +186,10 @@ function produce(proxies, targetPlatform, type, opts = {}) {
|
|||||||
throw new Error(`Target platform: ${targetPlatform} is not supported!`);
|
throw new Error(`Target platform: ${targetPlatform} is not supported!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sni_off_supported = /Surge|SurgeMac|Shadowrocket/i.test(
|
||||||
|
targetPlatform,
|
||||||
|
);
|
||||||
|
|
||||||
// filter unsupported proxies
|
// filter unsupported proxies
|
||||||
proxies = proxies.filter(
|
proxies = proxies.filter(
|
||||||
(proxy) =>
|
(proxy) =>
|
||||||
@@ -196,10 +200,22 @@ function produce(proxies, targetPlatform, type, opts = {}) {
|
|||||||
if (!isNotBlank(proxy.name)) {
|
if (!isNotBlank(proxy.name)) {
|
||||||
proxy.name = `${proxy.type} ${proxy.server}:${proxy.port}`;
|
proxy.name = `${proxy.type} ${proxy.server}:${proxy.port}`;
|
||||||
}
|
}
|
||||||
|
if (proxy['disable-sni']) {
|
||||||
|
if (sni_off_supported) {
|
||||||
|
proxy.sni = 'off';
|
||||||
|
} else if (!['tuic'].includes(proxy.type)) {
|
||||||
|
$.error(
|
||||||
|
`Target platform ${targetPlatform} does not support sni off. Proxy's fields (tls-fingerprint and skip-cert-verify) will be modified.`,
|
||||||
|
);
|
||||||
|
delete proxy.sni;
|
||||||
|
proxy['skip-cert-verify'] = true;
|
||||||
|
delete proxy['tls-fingerprint'];
|
||||||
|
}
|
||||||
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
});
|
});
|
||||||
|
|
||||||
$.info(`Producing proxies for target: ${targetPlatform}`);
|
$.log(`Producing proxies for target: ${targetPlatform}`);
|
||||||
if (typeof producer.type === 'undefined' || producer.type === 'SINGLE') {
|
if (typeof producer.type === 'undefined' || producer.type === 'SINGLE') {
|
||||||
let localPort = 10000;
|
let localPort = 10000;
|
||||||
const list = proxies
|
const list = proxies
|
||||||
|
|||||||
@@ -547,6 +547,7 @@ function URI_Hysteria2() {
|
|||||||
proxy.obfs = params.obfs;
|
proxy.obfs = params.obfs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proxy.ports = params.mport;
|
||||||
proxy['obfs-password'] = params['obfs-password'];
|
proxy['obfs-password'] = params['obfs-password'];
|
||||||
proxy['skip-cert-verify'] = /(TRUE)|1/i.test(params.insecure);
|
proxy['skip-cert-verify'] = /(TRUE)|1/i.test(params.insecure);
|
||||||
proxy.tfo = /(TRUE)|1/i.test(params.fastopen);
|
proxy.tfo = /(TRUE)|1/i.test(params.fastopen);
|
||||||
|
|||||||
@@ -177,7 +177,13 @@ username = & {
|
|||||||
password = comma match:[^,]+ { proxy.password = match.join(""); }
|
password = comma match:[^,]+ { proxy.password = match.join(""); }
|
||||||
|
|
||||||
tls = comma "tls" equals flag:bool { proxy.tls = flag; }
|
tls = comma "tls" equals flag:bool { proxy.tls = flag; }
|
||||||
sni = comma "sni" equals sni:domain { proxy.sni = sni; }
|
sni = comma "sni" equals sni:("off"/domain) {
|
||||||
|
if (sni === "off") {
|
||||||
|
proxy["disable-sni"] = true;
|
||||||
|
} else {
|
||||||
|
proxy.sni = sni;
|
||||||
|
}
|
||||||
|
}
|
||||||
tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-verify"] = flag; }
|
tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-verify"] = flag; }
|
||||||
tls_fingerprint = comma "server-cert-fingerprint-sha256" equals tls_fingerprint:$[^,]+ { proxy["tls-fingerprint"] = tls_fingerprint.trim(); }
|
tls_fingerprint = comma "server-cert-fingerprint-sha256" equals tls_fingerprint:$[^,]+ { proxy["tls-fingerprint"] = tls_fingerprint.trim(); }
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,13 @@ username = & {
|
|||||||
password = comma match:[^,]+ { proxy.password = match.join(""); }
|
password = comma match:[^,]+ { proxy.password = match.join(""); }
|
||||||
|
|
||||||
tls = comma "tls" equals flag:bool { proxy.tls = flag; }
|
tls = comma "tls" equals flag:bool { proxy.tls = flag; }
|
||||||
sni = comma "sni" equals sni:domain { proxy.sni = sni; }
|
sni = comma "sni" equals sni:("off"/domain) {
|
||||||
|
if (sni === "off") {
|
||||||
|
proxy["disable-sni"] = true;
|
||||||
|
} else {
|
||||||
|
proxy.sni = sni;
|
||||||
|
}
|
||||||
|
}
|
||||||
tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-verify"] = flag; }
|
tls_verification = comma "skip-cert-verify" equals flag:bool { proxy["skip-cert-verify"] = flag; }
|
||||||
tls_fingerprint = comma "server-cert-fingerprint-sha256" equals tls_fingerprint:$[^,]+ { proxy["tls-fingerprint"] = tls_fingerprint.trim(); }
|
tls_fingerprint = comma "server-cert-fingerprint-sha256" equals tls_fingerprint:$[^,]+ { proxy["tls-fingerprint"] = tls_fingerprint.trim(); }
|
||||||
|
|
||||||
|
|||||||
@@ -274,6 +274,9 @@ export default function URI_Producer() {
|
|||||||
`sni=${encodeURIComponent(proxy.sni)}`,
|
`sni=${encodeURIComponent(proxy.sni)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (proxy.ports) {
|
||||||
|
hysteria2params.push(`mport=${proxy.ports}`);
|
||||||
|
}
|
||||||
if (proxy['tls-fingerprint']) {
|
if (proxy['tls-fingerprint']) {
|
||||||
hysteria2params.push(
|
hysteria2params.push(
|
||||||
`pinSHA256=${encodeURIComponent(
|
`pinSHA256=${encodeURIComponent(
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ function AllRuleParser() {
|
|||||||
content: params[1],
|
content: params[1],
|
||||||
};
|
};
|
||||||
if (
|
if (
|
||||||
rule.type === 'IP-CIDR' ||
|
['IP-CIDR', 'IP-CIDR6', 'GEOIP'].includes(rule.type)
|
||||||
rule.type === 'IP-CIDR6'
|
|
||||||
) {
|
) {
|
||||||
rule.options = params.slice(2);
|
rule.options = params.slice(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ function QXFilter() {
|
|||||||
'SRC-IP',
|
'SRC-IP',
|
||||||
'IN-PORT',
|
'IN-PORT',
|
||||||
'PROTOCOL',
|
'PROTOCOL',
|
||||||
|
'GEOSITE',
|
||||||
|
'GEOIP',
|
||||||
];
|
];
|
||||||
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
|
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
|
||||||
|
|
||||||
@@ -29,6 +31,8 @@ function QXFilter() {
|
|||||||
function SurgeRuleSet() {
|
function SurgeRuleSet() {
|
||||||
const type = 'SINGLE';
|
const type = 'SINGLE';
|
||||||
const func = (rule) => {
|
const func = (rule) => {
|
||||||
|
const UNSUPPORTED = ['GEOSITE', 'GEOIP'];
|
||||||
|
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
|
||||||
let output = `${rule.type},${rule.content}`;
|
let output = `${rule.type},${rule.content}`;
|
||||||
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type)) {
|
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type)) {
|
||||||
output +=
|
output +=
|
||||||
@@ -43,7 +47,7 @@ function LoonRules() {
|
|||||||
const type = 'SINGLE';
|
const type = 'SINGLE';
|
||||||
const func = (rule) => {
|
const func = (rule) => {
|
||||||
// skip unsupported rules
|
// skip unsupported rules
|
||||||
const UNSUPPORTED = ['DEST-PORT', 'SRC-IP', 'IN-PORT', 'PROTOCOL'];
|
const UNSUPPORTED = ['SRC-IP', 'GEOSITE', 'GEOIP'];
|
||||||
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
|
if (UNSUPPORTED.indexOf(rule.type) !== -1) return null;
|
||||||
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type) && rule.options) {
|
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type) && rule.options) {
|
||||||
// Loon only supports the no-resolve option
|
// Loon only supports the no-resolve option
|
||||||
@@ -69,7 +73,7 @@ function ClashRuleProvider() {
|
|||||||
let output = `${TRANSFORM[rule.type] || rule.type},${
|
let output = `${TRANSFORM[rule.type] || rule.type},${
|
||||||
rule.content
|
rule.content
|
||||||
}`;
|
}`;
|
||||||
if (['IP-CIDR', 'IP-CIDR6'].includes(rule.type)) {
|
if (['IP-CIDR', 'IP-CIDR6', 'GEOIP'].includes(rule.type)) {
|
||||||
if (rule.options) {
|
if (rule.options) {
|
||||||
// Clash only supports the no-resolve option
|
// Clash only supports the no-resolve option
|
||||||
rule.options = rule.options.filter((option) =>
|
rule.options = rule.options.filter((option) =>
|
||||||
|
|||||||
@@ -128,10 +128,19 @@ async function doSync() {
|
|||||||
files.map((item) => [item.path, item]),
|
files.map((item) => [item.path, item]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const url = files[encodeURIComponent(artifact.name)]?.raw_url;
|
const raw_url =
|
||||||
artifact.url = isGitLab
|
files[encodeURIComponent(artifact.name)]?.raw_url;
|
||||||
? url
|
const new_url = isGitLab
|
||||||
: url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
? raw_url
|
||||||
|
: raw_url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
||||||
|
$.info(
|
||||||
|
`上传配置完成\n文件列表: ${Object.keys(files).join(
|
||||||
|
', ',
|
||||||
|
)}\n当前文件: ${encodeURIComponent(
|
||||||
|
artifact.name,
|
||||||
|
)}\n响应返回的原始链接: ${raw_url}\n处理完的新链接: ${new_url}`,
|
||||||
|
);
|
||||||
|
artifact.url = new_url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ async function downloadSubscription(req, res) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
sub.source !== 'local' ||
|
sub.source !== 'local' ||
|
||||||
['localFirst', 'remoteFirst'].includes(sub.mergeSources) ||
|
['localFirst', 'remoteFirst'].includes(sub.mergeSources)
|
||||||
url
|
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
url = `${url || sub.url}`
|
url = `${url || sub.url}`
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { ENV } from '@/vendor/open-api';
|
|||||||
import { failed, success } from '@/restful/response';
|
import { failed, success } from '@/restful/response';
|
||||||
import { updateArtifactStore, updateAvatar } from '@/restful/settings';
|
import { updateArtifactStore, updateAvatar } from '@/restful/settings';
|
||||||
import resourceCache from '@/utils/resource-cache';
|
import resourceCache from '@/utils/resource-cache';
|
||||||
|
import scriptResourceCache from '@/utils/script-resource-cache';
|
||||||
|
import headersResourceCache from '@/utils/headers-resource-cache';
|
||||||
import {
|
import {
|
||||||
GIST_BACKUP_FILE_NAME,
|
GIST_BACKUP_FILE_NAME,
|
||||||
GIST_BACKUP_KEY,
|
GIST_BACKUP_KEY,
|
||||||
@@ -73,6 +75,8 @@ async function refresh(_, res) {
|
|||||||
|
|
||||||
// 2. clear resource cache
|
// 2. clear resource cache
|
||||||
resourceCache.revokeAll();
|
resourceCache.revokeAll();
|
||||||
|
scriptResourceCache.revokeAll();
|
||||||
|
headersResourceCache.revokeAll();
|
||||||
success(res);
|
success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,11 +157,14 @@ async function gistBackup(req, res) {
|
|||||||
}
|
}
|
||||||
success(res);
|
success(res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
$.error(
|
||||||
|
`Failed to ${action} gist data.\nReason: ${err.message ?? err}`,
|
||||||
|
);
|
||||||
failed(
|
failed(
|
||||||
res,
|
res,
|
||||||
new InternalServerError(
|
new InternalServerError(
|
||||||
'BACKUP_FAILED',
|
'BACKUP_FAILED',
|
||||||
`Failed to ${action} data to gist!`,
|
`Failed to ${action} gist data!`,
|
||||||
`Reason: ${err.message ?? err}`,
|
`Reason: ${err.message ?? err}`,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -253,11 +253,7 @@ async function compareCollection(req, res) {
|
|||||||
errors[name] = err;
|
errors[name] = err;
|
||||||
|
|
||||||
$.error(
|
$.error(
|
||||||
`❌ 处理组合订阅中的子订阅: ${
|
`❌ 处理组合订阅 ${collection.name} 中的子订阅: ${sub.name}时出现错误:${err}!`,
|
||||||
sub.name
|
|
||||||
}时出现错误:${err}!进度--${
|
|
||||||
100 * (processed / subnames.length).toFixed(1)
|
|
||||||
}%`,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -563,10 +563,19 @@ async function syncArtifacts() {
|
|||||||
files.map((item) => [item.path, item]),
|
files.map((item) => [item.path, item]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const url = files[encodeURIComponent(artifact.name)]?.raw_url;
|
const raw_url =
|
||||||
artifact.url = isGitLab
|
files[encodeURIComponent(artifact.name)]?.raw_url;
|
||||||
? url
|
const new_url = isGitLab
|
||||||
: url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
? raw_url
|
||||||
|
: raw_url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
||||||
|
$.info(
|
||||||
|
`上传配置完成\n文件列表: ${Object.keys(files).join(
|
||||||
|
', ',
|
||||||
|
)}\n当前文件: ${encodeURIComponent(
|
||||||
|
artifact.name,
|
||||||
|
)}\n响应返回的原始链接: ${raw_url}\n处理完的新链接: ${new_url}`,
|
||||||
|
);
|
||||||
|
artifact.url = new_url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,10 +669,18 @@ async function syncArtifact(req, res) {
|
|||||||
isGitLab = true;
|
isGitLab = true;
|
||||||
files = Object.fromEntries(files.map((item) => [item.path, item]));
|
files = Object.fromEntries(files.map((item) => [item.path, item]));
|
||||||
}
|
}
|
||||||
const url = files[encodeURIComponent(artifact.name)]?.raw_url;
|
const raw_url = files[encodeURIComponent(artifact.name)]?.raw_url;
|
||||||
artifact.url = isGitLab
|
const new_url = isGitLab
|
||||||
? url
|
? raw_url
|
||||||
: url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
: raw_url?.replace(/\/raw\/[^/]*\/(.*)/, '/raw/$1');
|
||||||
|
$.info(
|
||||||
|
`上传配置完成\n文件列表: ${Object.keys(files).join(
|
||||||
|
', ',
|
||||||
|
)}\n当前文件: ${encodeURIComponent(
|
||||||
|
artifact.name,
|
||||||
|
)}\n响应返回的原始链接: ${raw_url}\n处理完的新链接: ${new_url}`,
|
||||||
|
);
|
||||||
|
artifact.url = new_url;
|
||||||
$.write(allArtifacts, ARTIFACTS_KEY);
|
$.write(allArtifacts, ARTIFACTS_KEY);
|
||||||
success(res, artifact);
|
success(res, artifact);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -138,10 +138,10 @@ export function parseFlowHeaders(flowHeaders) {
|
|||||||
return { expires, total, usage: { upload, download } };
|
return { expires, total, usage: { upload, download } };
|
||||||
}
|
}
|
||||||
export function flowTransfer(flow, unit = 'B') {
|
export function flowTransfer(flow, unit = 'B') {
|
||||||
const unitList = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'];
|
const unitList = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
let unitIndex = unitList.indexOf(unit);
|
let unitIndex = unitList.indexOf(unit);
|
||||||
|
|
||||||
return flow < 1024
|
return flow < 1024 || unitIndex === unitList.length - 1
|
||||||
? { value: flow.toFixed(1), unit: unit }
|
? { value: flow.toFixed(1), unit: unit }
|
||||||
: flowTransfer(flow / 1024, unitList[++unitIndex]);
|
: flowTransfer(flow / 1024, unitList[++unitIndex]);
|
||||||
}
|
}
|
||||||
|
|||||||
24
backend/src/vendor/open-api.js
vendored
24
backend/src/vendor/open-api.js
vendored
@@ -323,9 +323,19 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
|
|||||||
const request = isNode
|
const request = isNode
|
||||||
? eval("require('request')")
|
? eval("require('request')")
|
||||||
: $httpClient;
|
: $httpClient;
|
||||||
request[method.toLowerCase()](
|
const opts = JSON.parse(JSON.stringify(options));
|
||||||
JSON.parse(JSON.stringify(options)),
|
if (!isNode && opts.timeout) {
|
||||||
(err, response, body) => {
|
opts.timeout++;
|
||||||
|
let unit = 'ms';
|
||||||
|
// 这些客户端单位为 s
|
||||||
|
if (isSurge || isStash || isShadowRocket) {
|
||||||
|
opts.timeout = Math.ceil(opts.timeout / 1000);
|
||||||
|
unit = 's';
|
||||||
|
}
|
||||||
|
// Loon 为 ms
|
||||||
|
// console.log(`[httpClient timeout] ${opts.timeout}${unit}`);
|
||||||
|
}
|
||||||
|
request[method.toLowerCase()](opts, (err, response, body) => {
|
||||||
// if (err) {
|
// if (err) {
|
||||||
// console.log(err);
|
// console.log(err);
|
||||||
// } else {
|
// } else {
|
||||||
@@ -340,19 +350,19 @@ export function HTTP(defaultOptions = { baseURL: '' }) {
|
|||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else
|
else
|
||||||
resolve({
|
resolve({
|
||||||
statusCode:
|
statusCode: response.status || response.statusCode,
|
||||||
response.status || response.statusCode,
|
|
||||||
headers: response.headers,
|
headers: response.headers,
|
||||||
body,
|
body,
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let timeoutid;
|
let timeoutid;
|
||||||
|
|
||||||
const timer = timeout
|
const timer = timeout
|
||||||
? new Promise((_, reject) => {
|
? new Promise((_, reject) => {
|
||||||
|
// console.log(`[request timeout] ${timeout}ms`);
|
||||||
timeoutid = setTimeout(() => {
|
timeoutid = setTimeout(() => {
|
||||||
events.onTimeout();
|
events.onTimeout();
|
||||||
return reject(
|
return reject(
|
||||||
|
|||||||
@@ -17,4 +17,4 @@ hostname=sub.store
|
|||||||
http-request ^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))) script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js, requires-body=true, timeout=120, tag=Sub-Store Core
|
http-request ^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))) script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js, requires-body=true, timeout=120, tag=Sub-Store Core
|
||||||
http-request ^https?:\/\/sub\.store script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js, requires-body=true, timeout=120, tag=Sub-Store Simple
|
http-request ^https?:\/\/sub\.store script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js, requires-body=true, timeout=120, tag=Sub-Store Simple
|
||||||
|
|
||||||
cron "55 23 * * *" script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js, tag=Sub-Store Sync
|
cron "55 23 * * *" script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js, timeout=120, tag=Sub-Store Sync
|
||||||
@@ -10,6 +10,6 @@ hostname = %APPEND% sub.store
|
|||||||
[Script]
|
[Script]
|
||||||
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120,ability="{{{ability}}}"
|
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120,ability="{{{ability}}}"
|
||||||
|
|
||||||
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true
|
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true,timeout=120
|
||||||
|
|
||||||
{{{sync}}}=type=cron,cronexp="{{{cronexp}}}",wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
{{{sync}}}=type=cron,cronexp="{{{cronexp}}}",wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ hostname = %APPEND% sub.store
|
|||||||
[Script]
|
[Script]
|
||||||
# 主程序 已经去掉 Sub-Store Core 的参数 [,ability=http-client-policy] 不会爆内存,这个参数在 Surge 非常占用内存; 如果不需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 则可以使用此脚本
|
# 主程序 已经去掉 Sub-Store Core 的参数 [,ability=http-client-policy] 不会爆内存,这个参数在 Surge 非常占用内存; 如果不需要使用指定节点功能 例如[加旗帜脚本或者cname脚本] 则可以使用此脚本
|
||||||
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120
|
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120
|
||||||
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true
|
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true,timeout=120
|
||||||
|
|
||||||
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ hostname = %APPEND% sub.store
|
|||||||
|
|
||||||
[Script]
|
[Script]
|
||||||
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120,ability=http-client-policy
|
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120,ability=http-client-policy
|
||||||
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true
|
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true,timeout=120
|
||||||
|
|
||||||
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ hostname = %APPEND% sub.store
|
|||||||
|
|
||||||
[Script]
|
[Script]
|
||||||
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120
|
Sub-Store Core=type=http-request,pattern=^https?:\/\/sub\.store\/((download)|api\/(preview|sync|(utils\/node-info))),script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-1.min.js,requires-body=true,timeout=120
|
||||||
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true
|
Sub-Store Simple=type=http-request,pattern=^https?:\/\/sub\.store,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store-0.min.js,requires-body=true,timeout=120
|
||||||
|
|
||||||
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
Sub-Store Sync=type=cron,cronexp=55 23 * * *,wake-system=1,timeout=120,script-path=https://github.com/sub-store-org/Sub-Store/releases/latest/download/cron-sync-artifacts.min.js
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
|
|
||||||
// scriptResourceCache 缓存
|
// scriptResourceCache 缓存
|
||||||
// 可参考 https://t.me/zhetengsha/1003
|
// 可参考 https://t.me/zhetengsha/1003
|
||||||
|
// const cache = scriptResourceCache
|
||||||
|
// cache.set(id, data)
|
||||||
|
// cache.get(id)
|
||||||
|
|
||||||
// ProxyUtils 为节点处理工具
|
// ProxyUtils 为节点处理工具
|
||||||
// 可参考 https://t.me/zhetengsha/1066
|
// 可参考 https://t.me/zhetengsha/1066
|
||||||
@@ -35,6 +38,13 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// yaml, // yaml 解析和生成
|
// yaml, // yaml 解析和生成
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// 示例: 从 sni 文件中读取内容并进行节点操作
|
||||||
|
// const sni = await produceArtifact({
|
||||||
|
// type: 'file',
|
||||||
|
// name: 'sni' // 文件名
|
||||||
|
// });
|
||||||
|
// $server.sni = sni
|
||||||
|
|
||||||
// 1. Surge 输出 WireGuard 完整配置
|
// 1. Surge 输出 WireGuard 完整配置
|
||||||
|
|
||||||
// let proxies = await produceArtifact({
|
// let proxies = await produceArtifact({
|
||||||
@@ -49,7 +59,10 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
|
|
||||||
// 2. sing-box
|
// 2. sing-box
|
||||||
|
|
||||||
// 但是一般不需要这样用, 可参考 1. https://t.me/zhetengsha/1111 和 2. https://t.me/zhetengsha/1070
|
// 但是一般不需要这样用, 可参考
|
||||||
|
// 1. https://t.me/zhetengsha/1111
|
||||||
|
// 2. https://t.me/zhetengsha/1070
|
||||||
|
// 3. https://t.me/zhetengsha/1241
|
||||||
|
|
||||||
// let singboxProxies = await produceArtifact({
|
// let singboxProxies = await produceArtifact({
|
||||||
// type: 'subscription', // type: 'subscription' 或 'collection'
|
// type: 'subscription', // type: 'subscription' 或 'collection'
|
||||||
@@ -63,24 +76,42 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
|
|
||||||
// 3. clash.meta
|
// 3. clash.meta
|
||||||
|
|
||||||
// 但是一般不需要这样用, 可参考 1. https://t.me/zhetengsha/1111 和 2. https://t.me/zhetengsha/1070
|
// 但是一般不需要这样用, 可参考
|
||||||
|
// 1. https://t.me/zhetengsha/1111
|
||||||
|
// 2. https://t.me/zhetengsha/1070
|
||||||
|
// 3. https://t.me/zhetengsha/1234
|
||||||
|
|
||||||
// let clashMetaProxies = await produceArtifact({
|
// let clashMetaProxies = await produceArtifact({
|
||||||
// type: 'subscription',
|
// type: 'subscription',
|
||||||
// name: 'sub',
|
// name: 'sub',
|
||||||
// platform: 'ClashMeta',
|
// platform: 'ClashMeta',
|
||||||
// produceType: 'internal' // 'internal' produces an Array, otherwise produces a String( ProxyUtils.yaml.safeLoad('YAML String').proxies )
|
// produceType: 'internal' // 'internal' produces an Array, otherwise produces a String( ProxyUtils.yaml.safeLoad('YAML String').proxies )
|
||||||
// }))
|
// })
|
||||||
|
|
||||||
// // YAML
|
// // YAML
|
||||||
|
// ProxyUtils.yaml.load('YAML String')
|
||||||
|
// ProxyUtils.yaml.safeLoad('YAML String')
|
||||||
// $content = ProxyUtils.yaml.safeDump({})
|
// $content = ProxyUtils.yaml.safeDump({})
|
||||||
|
// $content = ProxyUtils.yaml.dump({})
|
||||||
|
|
||||||
|
// 一个往文件里插入本地节点的例子:
|
||||||
|
// const yaml = ProxyUtils.yaml.safeLoad($content ?? $files[0])
|
||||||
|
// let clashMetaProxies = await produceArtifact({
|
||||||
|
// type: 'collection',
|
||||||
|
// name: '机场',
|
||||||
|
// platform: 'ClashMeta',
|
||||||
|
// produceType: 'internal'
|
||||||
|
// })
|
||||||
|
// yaml.proxies.unshift(...clashMetaProxies)
|
||||||
|
// $content = ProxyUtils.yaml.dump(yaml)
|
||||||
|
|
||||||
|
|
||||||
// { $content, $files } will be passed to the next operator
|
// { $content, $files } 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 为机场订阅流量信息处理工具
|
||||||
// 可参考 https://t.me/zhetengsha/948
|
// 可参考:
|
||||||
// https://github.com/sub-store-org/Sub-Store/blob/31b6dd0507a9286d6ab834ec94ad3050f6bdc86b/backend/src/utils/download.js#L104
|
// 1. https://t.me/zhetengsha/948
|
||||||
|
|
||||||
// context 为传入的上下文
|
// context 为传入的上下文
|
||||||
// 有三种情况, 按需判断
|
// 有三种情况, 按需判断
|
||||||
|
|||||||
Reference in New Issue
Block a user