mirror of
https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-10 00:52:40 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b87c2ef55 |
5
.github/workflows/main.yml
vendored
5
.github/workflows/main.yml
vendored
@@ -64,8 +64,3 @@ jobs:
|
||||
./backend/dist/sub-store-parser.loon.min.js
|
||||
./backend/dist/cron-sync-artifacts.min.js
|
||||
./backend/dist/sub-store.bundle.js
|
||||
- name: Sync to GitLab
|
||||
env:
|
||||
GITLAB_PIPELINE_TOKEN: ${{ secrets.GITLAB_PIPELINE_TOKEN }}
|
||||
run: |
|
||||
curl -X POST --fail -F token=$GITLAB_PIPELINE_TOKEN -F ref=master https://gitlab.com/api/v4/projects/48891296/trigger/pipeline
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.
|
||||
</p>
|
||||
|
||||
[](https://github.com/sub-store-org/Sub-Store/actions/workflows/main.yml)     
|
||||
[](https://github.com/Peng-YM/Sub-Store/actions/workflows/main.yml)     
|
||||
|
||||
[](https://www.buymeacoffee.com/PengYM)
|
||||
|
||||
@@ -32,7 +32,7 @@ Core functionalities:
|
||||
- [x] V2RayN URI
|
||||
- [x] QX (SS, SSR, VMess, Trojan, HTTP)
|
||||
- [x] Loon (SS, SSR, VMess, Trojan, HTTP, WireGuard, VLESS)
|
||||
- [x] Surge (SS, VMess, Trojan, HTTP, TUIC, Snell, SSR(external, only for macOS), WireGuard(Surge to Surge))
|
||||
- [x] Surge (SS, VMess, Trojan, HTTP, TUIC, Snell)
|
||||
- [x] ShadowRocket (SS, SSR, VMess, Trojan, HTTP, Snell, VLESS, WireGuard, Hysteria)
|
||||
- [x] Clash.Meta (SS, SSR, VMess, Trojan, HTTP, Snell, VLESS, WireGuard, Hysteria)
|
||||
- [x] Stash (SS, SSR, VMess, Trojan, HTTP, Snell, VLESS, WireGuard, Hysteria)
|
||||
@@ -99,11 +99,6 @@ This project is under the GPL V3 LICENSE.
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2FPeng-YM%2FSub-Store?ref=badge_large)
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#sub-store-org/sub-store&Date)
|
||||
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
- Special thanks to @KOP-XIAO for his awesome resource-parser. Please give a [star](https://github.com/KOP-XIAO/QuantumultX) for his great work!
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* @updated: <%= updated %>
|
||||
* @version: <%= pkg.version %>
|
||||
* @author: Peng-YM
|
||||
* @github: https://github.com/sub-store-org/Sub-Store
|
||||
* @github: https://github.com/Peng-YM/Sub-Store
|
||||
* @documentation: https://www.notion.so/Sub-Store-6259586994d34c11a4ced5c406264b46
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sub-store",
|
||||
"version": "2.14.49",
|
||||
"version": "2.14.42",
|
||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
@@ -10,7 +10,7 @@
|
||||
"start": "nodemon -w src -w package.json --exec babel-node src/main.js",
|
||||
"build": "gulp",
|
||||
"bundle": "node bundle.js",
|
||||
"changelog": "conventional-changelog -p cli -i CHANGELOG.md -s"
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
|
||||
},
|
||||
"author": "Peng-YM",
|
||||
"license": "GPL-3.0",
|
||||
|
||||
@@ -136,21 +136,10 @@ function produce(proxies, targetPlatform) {
|
||||
|
||||
$.info(`Producing proxies for target: ${targetPlatform}`);
|
||||
if (typeof producer.type === 'undefined' || producer.type === 'SINGLE') {
|
||||
let localPort = 10000;
|
||||
return proxies
|
||||
.map((proxy) => {
|
||||
try {
|
||||
let line = producer.produce(proxy);
|
||||
if (
|
||||
line.length > 0 &&
|
||||
line.includes('__SubStoreLocalPort__')
|
||||
) {
|
||||
line = line.replace(
|
||||
/__SubStoreLocalPort__/g,
|
||||
localPort++,
|
||||
);
|
||||
}
|
||||
return line;
|
||||
return producer.produce(proxy);
|
||||
} catch (err) {
|
||||
$.error(
|
||||
`Cannot produce proxy: ${JSON.stringify(
|
||||
|
||||
@@ -215,6 +215,7 @@ function URI_VMess() {
|
||||
// V2rayN URI format
|
||||
params = JSON.parse(content);
|
||||
} catch (e) {
|
||||
// console.error(e);
|
||||
// Shadowrocket URI format
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let [__, base64Line, qs] = /(^[^?]+?)\/?\?(.*)$/.exec(line);
|
||||
@@ -739,7 +740,7 @@ function Surge_Socks5() {
|
||||
function Surge_Snell() {
|
||||
const name = 'Surge Snell Parser';
|
||||
const test = (line) => {
|
||||
return /^.*=\s*snell/.test(line.split(',')[0]);
|
||||
return /^.*=\s*snell?/.test(line.split(',')[0]);
|
||||
};
|
||||
const parse = (line) => getSurgeParser().parse(line);
|
||||
return { name, test, parse };
|
||||
@@ -748,15 +749,7 @@ function Surge_Snell() {
|
||||
function Surge_Tuic() {
|
||||
const name = 'Surge Tuic Parser';
|
||||
const test = (line) => {
|
||||
return /^.*=\s*tuic(-v5)?/.test(line.split(',')[0]);
|
||||
};
|
||||
const parse = (line) => getSurgeParser().parse(line);
|
||||
return { name, test, parse };
|
||||
}
|
||||
function Surge_WireGuard() {
|
||||
const name = 'Surge WireGuard Parser';
|
||||
const test = (line) => {
|
||||
return /^.*=\s*wireguard/.test(line.split(',')[0]);
|
||||
return /^.*=\s*tuic(-v5)??/.test(line.split(',')[0]);
|
||||
};
|
||||
const parse = (line) => getSurgeParser().parse(line);
|
||||
return { name, test, parse };
|
||||
@@ -775,7 +768,6 @@ export default [
|
||||
Surge_Http(),
|
||||
Surge_Snell(),
|
||||
Surge_Tuic(),
|
||||
Surge_WireGuard(),
|
||||
Surge_Socks5(),
|
||||
Loon_SS(),
|
||||
Loon_SSR(),
|
||||
|
||||
@@ -32,7 +32,7 @@ const grammars = String.raw`
|
||||
}
|
||||
}
|
||||
|
||||
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard) {
|
||||
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@@ -83,9 +83,6 @@ tuic_v5 = tag equals "tuic-v5" address (alpn/passwordk/uuidk/ip_version/tls_veri
|
||||
proxy.type = "tuic";
|
||||
proxy.version = 5;
|
||||
}
|
||||
wireguard = tag equals "wireguard" (section_name/no_error_alert/ip_version/underlying_proxy/test_url/others)* {
|
||||
proxy.type = "wireguard-surge";
|
||||
}
|
||||
socks5 = tag equals "socks5" address (username password)? (fast_open/others)* {
|
||||
proxy.type = "socks5";
|
||||
}
|
||||
@@ -190,10 +187,6 @@ udp_relay = comma "udp" equals flag:bool { proxy.udp = flag; }
|
||||
fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
|
||||
tfo = comma "tfo" equals flag:bool { proxy.tfo = flag; }
|
||||
ip_version = comma "ip-version" equals match:[^,]+ { proxy["ip-version"] = match.join(""); }
|
||||
section_name = comma "section-name" equals match:[^,]+ { proxy["section-name"] = match.join(""); }
|
||||
no_error_alert = comma "no-error-alert" equals match:[^,]+ { proxy["no-error-alert"] = match.join(""); }
|
||||
underlying_proxy = comma "underlying-proxy" equals match:[^,]+ { proxy["underlying-proxy"] = match.join(""); }
|
||||
test_url = comma "test-url" equals match:[^,]+ { proxy["test-url"] = match.join(""); }
|
||||
token = comma "token" equals match:[^,]+ { proxy.token = match.join(""); }
|
||||
alpn = comma "alpn" equals match:[^,]+ { proxy.alpn = match.join(""); }
|
||||
uuidk = comma "uuid" equals match:[^,]+ { proxy.uuid = match.join(""); }
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard) {
|
||||
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@@ -81,9 +81,6 @@ tuic_v5 = tag equals "tuic-v5" address (alpn/passwordk/uuidk/ip_version/tls_veri
|
||||
proxy.type = "tuic";
|
||||
proxy.version = 5;
|
||||
}
|
||||
wireguard = tag equals "wireguard" (section_name/no_error_alert/ip_version/underlying_proxy/test_url/others)* {
|
||||
proxy.type = "wireguard-surge";
|
||||
}
|
||||
socks5 = tag equals "socks5" address (username password)? (fast_open/others)* {
|
||||
proxy.type = "socks5";
|
||||
}
|
||||
@@ -188,10 +185,6 @@ udp_relay = comma "udp" equals flag:bool { proxy.udp = flag; }
|
||||
fast_open = comma "fast-open" equals flag:bool { proxy.tfo = flag; }
|
||||
tfo = comma "tfo" equals flag:bool { proxy.tfo = flag; }
|
||||
ip_version = comma "ip-version" equals match:[^,]+ { proxy["ip-version"] = match.join(""); }
|
||||
section_name = comma "section-name" equals match:[^,]+ { proxy["section-name"] = match.join(""); }
|
||||
no_error_alert = comma "no-error-alert" equals match:[^,]+ { proxy["no-error-alert"] = match.join(""); }
|
||||
underlying_proxy = comma "underlying-proxy" equals match:[^,]+ { proxy["underlying-proxy"] = match.join(""); }
|
||||
test_url = comma "test-url" equals match:[^,]+ { proxy["test-url"] = match.join(""); }
|
||||
token = comma "token" equals match:[^,]+ { proxy.token = match.join(""); }
|
||||
alpn = comma "alpn" equals match:[^,]+ { proxy.alpn = match.join(""); }
|
||||
uuidk = comma "uuid" equals match:[^,]+ { proxy.uuid = match.join(""); }
|
||||
|
||||
@@ -411,6 +411,7 @@ const DOMAIN_RESOLVERS = {
|
||||
},
|
||||
});
|
||||
const answers = resp.body.split(';').map((i) => i.split(',')[0]);
|
||||
console.log(`answers`, answers);
|
||||
if (answers.length === 0) {
|
||||
throw new Error('No answers');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import Surge_Producer from './surge';
|
||||
import SurgeMac_Producer from './surgemac';
|
||||
import Clash_Producer from './clash';
|
||||
import ClashMeta_Producer from './clashmeta';
|
||||
import Stash_Producer from './stash';
|
||||
@@ -18,7 +17,6 @@ function JSON_Producer() {
|
||||
export default {
|
||||
QX: QX_Producer(),
|
||||
Surge: Surge_Producer(),
|
||||
SurgeMac: SurgeMac_Producer(),
|
||||
Loon: Loon_Producer(),
|
||||
Clash: Clash_Producer(),
|
||||
ClashMeta: ClashMeta_Producer(),
|
||||
|
||||
@@ -29,8 +29,6 @@ export default function Surge_Producer() {
|
||||
return snell(proxy);
|
||||
case 'tuic':
|
||||
return tuic(proxy);
|
||||
case 'wireguard-surge':
|
||||
return wireguard(proxy);
|
||||
}
|
||||
throw new Error(
|
||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`,
|
||||
@@ -291,34 +289,6 @@ function tuic(proxy) {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function wireguard(proxy) {
|
||||
const result = new Result(proxy);
|
||||
|
||||
result.append(`${proxy.name}=wireguard`);
|
||||
|
||||
result.appendIfPresent(
|
||||
`,section-name=${proxy['section-name']}`,
|
||||
'section-name',
|
||||
);
|
||||
result.appendIfPresent(
|
||||
`,no-error-alert=${proxy['no-error-alert']}`,
|
||||
'no-error-alert',
|
||||
);
|
||||
result.appendIfPresent(
|
||||
`,underlying-proxy=${proxy['underlying-proxy']}`,
|
||||
'underlying-proxy',
|
||||
);
|
||||
result.appendIfPresent(
|
||||
`,ip-version=${ipVersions[proxy['ip-version']] || proxy['ip-version']}`,
|
||||
'ip-version',
|
||||
);
|
||||
|
||||
// test-url
|
||||
result.appendIfPresent(`,test-url=${proxy['test-url']}`, 'test-url');
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
function handleTransport(result, proxy) {
|
||||
if (isPresent(proxy, 'network')) {
|
||||
if (proxy.network === 'ws') {
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Result } from './utils';
|
||||
import Surge_Producer from './surge';
|
||||
|
||||
const targetPlatform = 'SurgeMac';
|
||||
|
||||
const surge_Producer = Surge_Producer();
|
||||
|
||||
export default function SurgeMac_Producer() {
|
||||
const produce = (proxy) => {
|
||||
switch (proxy.type) {
|
||||
case 'ssr':
|
||||
return shadowsocksr(proxy);
|
||||
case 'ss':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'trojan':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'vmess':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'http':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'socks5':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'snell':
|
||||
return surge_Producer.produce(proxy);
|
||||
case 'tuic':
|
||||
return surge_Producer.produce(proxy);
|
||||
}
|
||||
throw new Error(
|
||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`,
|
||||
);
|
||||
};
|
||||
return { produce };
|
||||
}
|
||||
|
||||
function shadowsocksr(proxy) {
|
||||
const result = new Result(proxy);
|
||||
|
||||
proxy.local_port = '__SubStoreLocalPort__';
|
||||
proxy.local_address = proxy.local_address ?? '127.0.0.1';
|
||||
|
||||
result.append(
|
||||
`${proxy.name} = external, exec = "${
|
||||
proxy.exec || '/usr/local/bin/ssr-local'
|
||||
}", address = "${proxy.server}", local-port = ${proxy.local_port}`,
|
||||
);
|
||||
|
||||
for (const [key, value] of Object.entries({
|
||||
cipher: '-m',
|
||||
obfs: '-o',
|
||||
password: '-k',
|
||||
port: '-p',
|
||||
protocol: '-O',
|
||||
'protocol-param': '-G',
|
||||
server: '-s',
|
||||
local_port: '-l',
|
||||
local_address: '-b',
|
||||
})) {
|
||||
result.appendIfPresent(
|
||||
`, args = "${value}", args = "${proxy[key]}"`,
|
||||
key,
|
||||
);
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
@@ -47,7 +47,7 @@ function AllRuleParser() {
|
||||
}
|
||||
if (!matched) throw new Error('Invalid rule type: ' + rawType);
|
||||
} catch (e) {
|
||||
console.log(`Failed to parse line: ${line}\n Reason: ${e}`);
|
||||
console.error(`Failed to parse line: ${line}\n Reason: ${e}`);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* ╚══════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
|
||||
* Advanced Subscription Manager for QX, Loon, Surge and Clash.
|
||||
* @author: Peng-YM
|
||||
* @github: https://github.com/sub-store-org/Sub-Store
|
||||
* @github: https://github.com/Peng-YM/Sub-Store
|
||||
* @documentation: https://www.notion.so/Sub-Store-6259586994d34c11a4ced5c406264b46
|
||||
*/
|
||||
import { version } from '../package.json';
|
||||
|
||||
@@ -118,23 +118,6 @@ async function gistBackup(req, res) {
|
||||
case 'download':
|
||||
$.info(`还原备份中...`);
|
||||
content = await gist.download(GIST_BACKUP_FILE_NAME);
|
||||
try {
|
||||
if (
|
||||
Object.keys(JSON.parse(content).settings).length ===
|
||||
0
|
||||
) {
|
||||
throw new Error(
|
||||
'备份文件应该至少包含 settings 字段',
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
$.error(
|
||||
`Gist 备份文件校验失败, 无法还原\nReason: ${
|
||||
err.message ?? err
|
||||
}`,
|
||||
);
|
||||
throw new Error('Gist 备份文件校验失败, 无法还原');
|
||||
}
|
||||
// restore settings
|
||||
$.write(content, '#sub-store');
|
||||
if ($.env.isNode) {
|
||||
@@ -142,9 +125,8 @@ async function gistBackup(req, res) {
|
||||
$.cache = content;
|
||||
$.persistCache();
|
||||
}
|
||||
$.info(`perform migration after restoring from gist...`);
|
||||
// perform migration after restoring from gist
|
||||
migrate();
|
||||
$.info(`migration completed`);
|
||||
$.info(`还原备份完成`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -44,12 +44,8 @@ export async function updateGitHubAvatar() {
|
||||
.then((resp) => JSON.parse(resp.body));
|
||||
settings.avatarUrl = data['avatar_url'];
|
||||
$.write(settings, SETTINGS_KEY);
|
||||
} catch (err) {
|
||||
$.error(
|
||||
`Failed to fetch GitHub avatar for User: ${username}. Reason: ${
|
||||
err.message ?? err
|
||||
}`,
|
||||
);
|
||||
} catch (e) {
|
||||
$.error('Failed to fetch GitHub avatar for User: ' + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,11 +67,7 @@ export async function updateArtifactStore() {
|
||||
$.write(settings, SETTINGS_KEY);
|
||||
}
|
||||
} catch (err) {
|
||||
$.error(
|
||||
`Failed to fetch artifact store for User: ${githubUser}. Reason: ${
|
||||
err.message ?? err
|
||||
}`,
|
||||
);
|
||||
$.error('Failed to fetch artifact store for User: ' + githubUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function register($app) {
|
||||
function sortSubs(req, res) {
|
||||
const orders = req.body;
|
||||
const allSubs = $.read(SUBS_KEY);
|
||||
allSubs.sort((a, b) => orders.indexOf(a.name) - orders.indexOf(b.name));
|
||||
allSubs.sort((a, b) => orders.indexOf(a) - orders.indexOf(b));
|
||||
$.write(allSubs, SUBS_KEY);
|
||||
success(res, allSubs);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ function sortSubs(req, res) {
|
||||
function sortCollections(req, res) {
|
||||
const orders = req.body;
|
||||
const allCols = $.read(COLLECTIONS_KEY);
|
||||
allCols.sort((a, b) => orders.indexOf(a.name) - orders.indexOf(b.name));
|
||||
allCols.sort((a, b) => orders.indexOf(a) - orders.indexOf(b));
|
||||
$.write(allCols, COLLECTIONS_KEY);
|
||||
success(res, allCols);
|
||||
}
|
||||
@@ -27,9 +27,7 @@ function sortCollections(req, res) {
|
||||
function sortArtifacts(req, res) {
|
||||
const orders = req.body;
|
||||
const allArtifacts = $.read(ARTIFACTS_KEY);
|
||||
allArtifacts.sort(
|
||||
(a, b) => orders.indexOf(a.name) - orders.indexOf(b.name),
|
||||
);
|
||||
allArtifacts.sort((a, b) => orders.indexOf(a) - orders.indexOf(b));
|
||||
$.write(allArtifacts, ARTIFACTS_KEY);
|
||||
success(res, allArtifacts);
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ export function getPlatformFromHeaders(headers) {
|
||||
}
|
||||
if (UA.indexOf('Quantumult%20X') !== -1) {
|
||||
return 'QX';
|
||||
} else if (UA.indexOf('Surge Mac') !== -1) {
|
||||
return 'SurgeMac';
|
||||
} else if (UA.indexOf('Surge') !== -1) {
|
||||
return 'Surge';
|
||||
} else if (UA.indexOf('Decar') !== -1 || UA.indexOf('Loon') !== -1) {
|
||||
|
||||
2
backend/src/vendor/express.js
vendored
2
backend/src/vendor/express.js
vendored
@@ -17,7 +17,7 @@ export default function express({ substore: $, port }) {
|
||||
const express_ = eval(`require("express")`);
|
||||
const bodyParser = eval(`require("body-parser")`);
|
||||
const app = express_();
|
||||
app.use(bodyParser.json({ verify: rawBodySaver, limit: '1mb' }));
|
||||
app.use(bodyParser.json({ verify: rawBodySaver }));
|
||||
app.use(
|
||||
bodyParser.urlencoded({ verify: rawBodySaver, extended: true }),
|
||||
);
|
||||
|
||||
24
backend/src/vendor/open-api.js
vendored
24
backend/src/vendor/open-api.js
vendored
@@ -49,23 +49,18 @@ export class OpenAPI {
|
||||
|
||||
if (isNode) {
|
||||
// create a json for root cache
|
||||
const basePath =
|
||||
eval('process.env.SUB_STORE_DATA_BASE_PATH') || '.';
|
||||
let rootPath = `${basePath}/root.json`;
|
||||
|
||||
this.log(`Root path: ${rootPath}`);
|
||||
if (!this.node.fs.existsSync(rootPath)) {
|
||||
this.node.fs.writeFileSync(rootPath, JSON.stringify({}), {
|
||||
let fpath = 'root.json';
|
||||
if (!this.node.fs.existsSync(fpath)) {
|
||||
this.node.fs.writeFileSync(fpath, JSON.stringify({}), {
|
||||
flag: 'wx',
|
||||
});
|
||||
this.root = {};
|
||||
} else {
|
||||
this.root = JSON.parse(this.node.fs.readFileSync(`${rootPath}`));
|
||||
this.root = JSON.parse(this.node.fs.readFileSync(`${fpath}`));
|
||||
}
|
||||
|
||||
// create a json file with the given name if not exists
|
||||
let fpath = `${basePath}/${this.name}.json`;
|
||||
this.log(`Data path: ${fpath}`);
|
||||
fpath = `${this.name}.json`;
|
||||
if (!this.node.fs.existsSync(fpath)) {
|
||||
this.node.fs.writeFileSync(fpath, JSON.stringify({}), {
|
||||
flag: 'wx',
|
||||
@@ -73,7 +68,7 @@ export class OpenAPI {
|
||||
this.cache = {};
|
||||
} else {
|
||||
this.cache = JSON.parse(
|
||||
this.node.fs.readFileSync(`${fpath}`),
|
||||
this.node.fs.readFileSync(`${this.name}.json`),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -85,17 +80,14 @@ export class OpenAPI {
|
||||
if (isQX) $prefs.setValueForKey(data, this.name);
|
||||
if (isLoon || isSurge) $persistentStore.write(data, this.name);
|
||||
if (isNode) {
|
||||
const basePath =
|
||||
eval('process.env.SUB_STORE_DATA_BASE_PATH') || '.';
|
||||
|
||||
this.node.fs.writeFileSync(
|
||||
`${basePath}/${this.name}.json`,
|
||||
`${this.name}.json`,
|
||||
data,
|
||||
{ flag: 'w' },
|
||||
(err) => console.log(err),
|
||||
);
|
||||
this.node.fs.writeFileSync(
|
||||
`${basePath}/root.json`,
|
||||
'root.json',
|
||||
JSON.stringify(this.root, null, 2),
|
||||
{ flag: 'w' },
|
||||
(err) => console.log(err),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#!desc=高级订阅管理工具
|
||||
#!openUrl=https://sub.store
|
||||
#!author=Peng-YM
|
||||
#!homepage=https://github.com/sub-store-org/Sub-Store
|
||||
#!homepage=https://github.com/Peng-YM/Sub-Store
|
||||
#!icon=https://raw.githubusercontent.com/58xinian/icon/master/Sub-Store1.png
|
||||
#!select = 节点缓存有效期,1分钟,5分钟,10分钟,30分钟,1小时,2小时,3小时,6小时,12小时,24小时,48小时,72小时,参数传入
|
||||
|
||||
|
||||
@@ -1,32 +1,20 @@
|
||||
# Sub-Store 配置指南
|
||||
|
||||
## 查看更新说明:
|
||||
|
||||
Sub-Store Releases: [`https://github.com/sub-store-org/Sub-Store/releases`](https://github.com/sub-store-org/Sub-Store/releases)
|
||||
|
||||
Telegram 频道: [`https://t.me/cool_scripts` ](https://t.me/cool_scripts)
|
||||
|
||||
## 脚本配置:
|
||||
|
||||
### 1. Loon
|
||||
安装使用 插件 [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Loon.plugin`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Loon.plugin) 即可。
|
||||
|
||||
安装使用[插件](https://raw.githubusercontent.com/Peng-YM/Sub-Store/master/config/Loon.plugin)即可。
|
||||
### 2. Surge
|
||||
1. 官方默认版模块(目前不带 ability 参数, 不保证以后不会改动): [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule)
|
||||
|
||||
2. 固定带 ability 参数版本,可能会爆内存, 如果需要使用指定节点功能 例如[加国旗脚本或者cname脚本] 请使用此带 ability 参数版本: [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-ability.sgmodule)
|
||||
|
||||
3. 固定不带 ability 参数版本: [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-Noability.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge-Noability.sgmodule)
|
||||
|
||||
安装使用[模块](https://raw.githubusercontent.com/Peng-YM/Sub-Store/master/config/Surge.sgmodule)即可。
|
||||
|
||||
### 3. QX
|
||||
订阅 重写 [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/QX.snippet`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/QX.snippet) 即可。
|
||||
订阅[重写](https://raw.githubusercontent.com/Peng-YM/Sub-Store/master/config/QX.snippet)即可
|
||||
|
||||
### 4. Stash
|
||||
安装使用 覆写 [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Stash.stoverride`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Stash.stoverride) 即可。
|
||||
安装使用[ Stash 覆写](https://raw.githubusercontent.com/Peng-YM/Sub-Store/master/config/Stash.stoverride)即可。
|
||||
|
||||
### 5. Shadowrocket
|
||||
安装使用 模块 [`https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule`](https://raw.githubusercontent.com/sub-store-org/Sub-Store/master/config/Surge.sgmodule) 即可。
|
||||
安装使用[模块](https://raw.githubusercontent.com/Peng-YM/Sub-Store/master/config/Surge.sgmodule)即可。
|
||||
|
||||
## 使用 Sub-Store
|
||||
1. 使用 Safari 打开这个 https://sub.store 如网页正常打开并且未弹出任何错误提示,说明 Sub-Store 已经配置成功。
|
||||
|
||||
Reference in New Issue
Block a user