mirror of
				https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
				synced 2025-10-31 18:21:10 +08:00 
			
		
		
		
	feat: 实验性支持本地脚本复用
This commit is contained in:
		
							parent
							
								
									2c89a0ddbd
								
							
						
					
					
						commit
						33a17c2d66
					
				| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "sub-store", | ||||
|   "version": "2.14.52", | ||||
|   "version": "2.14.53", | ||||
|   "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", | ||||
|   "main": "src/main.js", | ||||
|   "scripts": { | ||||
|  | ||||
| @ -2,6 +2,7 @@ export const SCHEMA_VERSION_KEY = 'schemaVersion'; | ||||
| export const SETTINGS_KEY = 'settings'; | ||||
| export const SUBS_KEY = 'subs'; | ||||
| export const COLLECTIONS_KEY = 'collections'; | ||||
| export const FILES_KEY = 'files'; | ||||
| export const ARTIFACTS_KEY = 'artifacts'; | ||||
| export const RULES_KEY = 'rules'; | ||||
| export const GIST_BACKUP_KEY = 'Auto Generated Sub-Store Backup'; | ||||
|  | ||||
							
								
								
									
										103
									
								
								backend/src/restful/file.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								backend/src/restful/file.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | ||||
| import { deleteByName, findByName, updateByName } from '@/utils/database'; | ||||
| import { FILES_KEY } from '@/constants'; | ||||
| import { failed, success } from '@/restful/response'; | ||||
| import $ from '@/core/app'; | ||||
| import { RequestInvalidError, ResourceNotFoundError } from '@/restful/errors'; | ||||
| 
 | ||||
| export default function register($app) { | ||||
|     if (!$.read(FILES_KEY)) $.write([], FILES_KEY); | ||||
| 
 | ||||
|     $app.route('/api/file/:name') | ||||
|         .get(getFile) | ||||
|         .patch(updateFile) | ||||
|         .delete(deleteFile); | ||||
| 
 | ||||
|     $app.route('/api/files').get(getAllFiles).post(createFile).put(replaceFile); | ||||
| } | ||||
| 
 | ||||
| // file API
 | ||||
| function createFile(req, res) { | ||||
|     const file = req.body; | ||||
|     $.info(`正在创建文件:${file.name}`); | ||||
|     const allFiles = $.read(FILES_KEY); | ||||
|     if (findByName(allFiles, file.name)) { | ||||
|         failed( | ||||
|             res, | ||||
|             new RequestInvalidError( | ||||
|                 'DUPLICATE_KEY', | ||||
|                 `File ${file.name} already exists.`, | ||||
|             ), | ||||
|         ); | ||||
|     } | ||||
|     allFiles.push(file); | ||||
|     $.write(allFiles, FILES_KEY); | ||||
|     success(res, file, 201); | ||||
| } | ||||
| 
 | ||||
| function getFile(req, res) { | ||||
|     let { name } = req.params; | ||||
|     name = decodeURIComponent(name); | ||||
|     const allFiles = $.read(FILES_KEY); | ||||
|     const file = findByName(allFiles, name); | ||||
|     if (file) { | ||||
|         success(res, file); | ||||
|     } else { | ||||
|         failed( | ||||
|             res, | ||||
|             new ResourceNotFoundError( | ||||
|                 `FILE_NOT_FOUND`, | ||||
|                 `File ${name} does not exist`, | ||||
|                 404, | ||||
|             ), | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function updateFile(req, res) { | ||||
|     let { name } = req.params; | ||||
|     name = decodeURIComponent(name); | ||||
|     let file = req.body; | ||||
|     const allFiles = $.read(FILES_KEY); | ||||
|     const oldFile = findByName(allFiles, name); | ||||
|     if (oldFile) { | ||||
|         const newFile = { | ||||
|             ...oldFile, | ||||
|             ...file, | ||||
|         }; | ||||
|         $.info(`正在更新文件:${name}...`); | ||||
| 
 | ||||
|         updateByName(allFiles, name, newFile); | ||||
|         $.write(allFiles, FILES_KEY); | ||||
|         success(res, newFile); | ||||
|     } else { | ||||
|         failed( | ||||
|             res, | ||||
|             new ResourceNotFoundError( | ||||
|                 'RESOURCE_NOT_FOUND', | ||||
|                 `File ${name} does not exist!`, | ||||
|             ), | ||||
|             404, | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function deleteFile(req, res) { | ||||
|     let { name } = req.params; | ||||
|     name = decodeURIComponent(name); | ||||
|     $.info(`正在删除文件:${name}`); | ||||
|     let allFiles = $.read(FILES_KEY); | ||||
|     deleteByName(allFiles, name); | ||||
|     $.write(allFiles, FILES_KEY); | ||||
|     success(res); | ||||
| } | ||||
| 
 | ||||
| function getAllFiles(req, res) { | ||||
|     const allFiles = $.read(FILES_KEY); | ||||
|     success(res, allFiles); | ||||
| } | ||||
| 
 | ||||
| function replaceFile(req, res) { | ||||
|     const allFiles = req.body; | ||||
|     $.write(allFiles, FILES_KEY); | ||||
|     success(res); | ||||
| } | ||||
| @ -4,6 +4,7 @@ import $ from '@/core/app'; | ||||
| import registerSubscriptionRoutes from './subscriptions'; | ||||
| import registerCollectionRoutes from './collections'; | ||||
| import registerArtifactRoutes from './artifacts'; | ||||
| import registerFileRoutes from './file'; | ||||
| import registerSyncRoutes from './sync'; | ||||
| import registerDownloadRoutes from './download'; | ||||
| import registerSettingRoutes from './settings'; | ||||
| @ -23,6 +24,7 @@ export default function serve() { | ||||
|     registerSortingRoutes($app); | ||||
|     registerSettingRoutes($app); | ||||
|     registerArtifactRoutes($app); | ||||
|     registerFileRoutes($app); | ||||
|     registerSyncRoutes($app); | ||||
|     registerNodeInfoRoutes($app); | ||||
|     registerMiscRoutes($app); | ||||
|  | ||||
| @ -1,10 +1,28 @@ | ||||
| import { FILES_KEY } from '@/constants'; | ||||
| import { findByName } from '@/utils/database'; | ||||
| import { HTTP, ENV } from '@/vendor/open-api'; | ||||
| import { hex_md5 } from '@/vendor/md5'; | ||||
| import resourceCache from '@/utils/resource-cache'; | ||||
| import $ from '@/core/app'; | ||||
| 
 | ||||
| const tasks = new Map(); | ||||
| 
 | ||||
| export default async function download(url, ua) { | ||||
|     const downloadUrlMatch = url.match(/^\/api\/file\/(.+)/); | ||||
|     if (downloadUrlMatch) { | ||||
|         let fileName = downloadUrlMatch?.[1]; | ||||
|         if (fileName == null) { | ||||
|             throw new Error(`本地文件 URL 无效: ${url}`); | ||||
|         } | ||||
|         fileName = decodeURIComponent(fileName); | ||||
|         const allFiles = $.read(FILES_KEY); | ||||
|         const file = findByName(allFiles, fileName); | ||||
|         if (!file) { | ||||
|             throw new Error(`找不到本地文件: ${fileName}`); | ||||
|         } | ||||
|         return file.content; | ||||
|     } | ||||
| 
 | ||||
|     const { isNode } = ENV(); | ||||
|     ua = ua || 'Quantumult%20X/1.0.29 (iPhone14,5; iOS 15.4.1)'; | ||||
|     const id = hex_md5(ua + url); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 xream
						xream