From 37aa38e2331a2b6e0f29e36c0de8e08a5726a36f Mon Sep 17 00:00:00 2001 From: Li Guangming Date: Mon, 22 Sep 2025 10:15:17 +0800 Subject: [PATCH] feat: add common resource parser --- backend/bundle-esbuild.js | 4 ++ backend/src/products/resource-parser.js | 61 +++++++++++++++++++++++++ backend/src/vendor/open-api.js | 41 +++++++++-------- 3 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 backend/src/products/resource-parser.js diff --git a/backend/bundle-esbuild.js b/backend/bundle-esbuild.js index 05d6bd66c..d8d318013 100644 --- a/backend/bundle-esbuild.js +++ b/backend/bundle-esbuild.js @@ -14,6 +14,10 @@ const { build } = require('esbuild'); src: 'src/products/resource-parser.loon.js', dest: 'dist/sub-store-parser.loon.min.js', }, + { + src: 'src/products/resource-parser.js', + dest: 'dist/sub-store-parser.min.js', + }, { src: 'src/products/cron-sync-artifacts.js', dest: 'dist/cron-sync-artifacts.min.js', diff --git a/backend/src/products/resource-parser.js b/backend/src/products/resource-parser.js new file mode 100644 index 000000000..bdc586c97 --- /dev/null +++ b/backend/src/products/resource-parser.js @@ -0,0 +1,61 @@ +/* eslint-disable no-undef */ +import { ProxyUtils } from '@/core/proxy-utils'; +import { RuleUtils } from '@/core/rule-utils'; +import { version } from '../../package.json'; + +let result = ''; +let resource = typeof $resource !== 'undefined' ? $resource : ''; +let resourceType = typeof $resourceType !== 'undefined' ? $resourceType : ''; +let targetPlatform = typeof $targetPlatform !== 'undefined' ? $targetPlatform : ''; + +!(async () => { + console.log( + ` + ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ + Sub-Store -- v${version} + ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ + `, + ); + + let arg; + if (typeof $argument != 'undefined') { + arg = Object.fromEntries( + $argument.split('&').map((item) => item.split('=')), + ); + } else { + arg = {}; + } + + console.log(`arg: ${JSON.stringify(arg)}`); + + const RESOURCE_TYPE = { + PROXY: 1, + RULE: 2, + }; + + if (resourceType === RESOURCE_TYPE.PROXY) { + try { + let proxies = ProxyUtils.parse(resource); + result = ProxyUtils.produce(proxies, targetPlatform, undefined, { + 'include-unsupported-proxy':false, + }); + } catch (e) { + console.log('解析器: 使用 resource 出现错误'); + console.log(e.message ?? e); + } + } else if (resourceType === RESOURCE_TYPE.RULE) { + try { + const rules = RuleUtils.parse(resource); + result = RuleUtils.produce(rules, targetPlatform); + } catch (e) { + console.log(e.message ?? e); + } + } +})() + .catch(async (e) => { + console.log('解析器: 出现错误'); + console.log(e.message ?? e); + }) + .finally(() => { + $done(result || ''); + }); diff --git a/backend/src/vendor/open-api.js b/backend/src/vendor/open-api.js index 747dda0cd..c3384cbd5 100644 --- a/backend/src/vendor/open-api.js +++ b/backend/src/vendor/open-api.js @@ -47,10 +47,13 @@ export class OpenAPI { this.http = HTTP(); this.env = ENV(); + const isNode = this.env.isNode && Object.values(this.env).filter((a) => a).length == 1; + if (isNode) { const dotenv = eval(`require("dotenv")`); dotenv.config(); } + this.node = (() => { if (isNode) { const fs = eval("require('fs')"); @@ -80,13 +83,13 @@ export class OpenAPI { initCache() { if (isQX) this.cache = JSON.parse($prefs.valueForKey(this.name) || '{}'); - if (isLoon || isSurge) + else if (isLoon || isSurge) this.cache = JSON.parse($persistentStore.read(this.name) || '{}'); - if (isGUIforCores) + else if (isGUIforCores) this.cache = JSON.parse( $Plugins.SubStoreCache.get(this.name) || '{}', ); - if (isNode) { + else if (isNode) { // create a json for root cache const basePath = eval('process.env.SUB_STORE_DATA_BASE_PATH') || '.'; @@ -157,9 +160,9 @@ export class OpenAPI { persistCache() { const data = JSON.stringify(this.cache, null, 2); if (isQX) $prefs.setValueForKey(data, this.name); - if (isLoon || isSurge) $persistentStore.write(data, this.name); - if (isGUIforCores) $Plugins.SubStoreCache.set(this.name, data); - if (isNode) { + else if (isLoon || isSurge) $persistentStore.write(data, this.name); + else if (isGUIforCores) $Plugins.SubStoreCache.set(this.name, data); + else if (isNode) { const basePath = eval('process.env.SUB_STORE_DATA_BASE_PATH') || '.'; @@ -185,13 +188,13 @@ export class OpenAPI { if (isSurge || isLoon) { return $persistentStore.write(data, key); } - if (isQX) { + else if (isQX) { return $prefs.setValueForKey(data, key); } - if (isNode) { + else if (isNode) { this.root[key] = data; } - if (isGUIforCores) { + else if (isGUIforCores) { return $Plugins.SubStoreCache.set(key, data); } } else { @@ -207,13 +210,13 @@ export class OpenAPI { if (isSurge || isLoon) { return $persistentStore.read(key); } - if (isQX) { + else if (isQX) { return $prefs.valueForKey(key); } - if (isNode) { + else if (isNode) { return this.root[key]; } - if (isGUIforCores) { + else if (isGUIforCores) { return $Plugins.SubStoreCache.get(key); } } else { @@ -228,13 +231,13 @@ export class OpenAPI { if (isSurge || isLoon) { return $persistentStore.write(null, key); } - if (isQX) { + else if (isQX) { return $prefs.removeValueForKey(key); } - if (isNode) { + else if (isNode) { delete this.root[key]; } - if (isGUIforCores) { + else if (isGUIforCores) { return $Plugins.SubStoreCache.remove(key); } } else { @@ -249,7 +252,7 @@ export class OpenAPI { const mediaURL = options['media-url']; if (isQX) $notify(title, subtitle, content, options); - if (isSurge) { + else if (isSurge) { $notification.post( title, subtitle, @@ -259,7 +262,7 @@ export class OpenAPI { }, ); } - if (isLoon) { + else if (isLoon) { let opts = {}; if (openURL) opts['openUrl'] = openURL; if (mediaURL) opts['mediaUrl'] = mediaURL; @@ -269,7 +272,7 @@ export class OpenAPI { $notification.post(title, subtitle, content, opts); } } - if (isNode) { + else if (isNode) { const content_ = content + (openURL ? `\n点击跳转: ${openURL}` : '') + @@ -335,7 +338,7 @@ export class OpenAPI { } } } - if (isGUIforCores) { + else if (isGUIforCores) { $Plugins.Notify(title, subtitle + '\n' + content); } }