feat: 增强 VMess URI 解析兼容性; 修改导出文件名格式

This commit is contained in:
xream 2025-03-13 20:19:05 +08:00
parent 1faa3fb793
commit 1281df59f3
No known key found for this signature in database
GPG Key ID: 1D2C5225471789F9
7 changed files with 41 additions and 58 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "sub-store", "name": "sub-store",
"version": "2.18.2", "version": "2.18.3",
"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": {

View File

@ -342,7 +342,7 @@ function URI_VMess() {
}; };
const parse = (line) => { const parse = (line) => {
line = line.split('vmess://')[1]; line = line.split('vmess://')[1];
let content = Base64.decode(line); let content = Base64.decode(line.replace(/\?.*?$/, ''));
if (/=\s*vmess/.test(content)) { if (/=\s*vmess/.test(content)) {
// Quantumult VMess URI format // Quantumult VMess URI format
const partitions = content.split(',').map((p) => p.trim()); const partitions = content.split(',').map((p) => p.trim());

View File

@ -3,6 +3,7 @@ import { COLLECTIONS_KEY, ARTIFACTS_KEY } from '@/constants';
import { failed, success } from '@/restful/response'; import { failed, success } from '@/restful/response';
import $ from '@/core/app'; import $ from '@/core/app';
import { RequestInvalidError, ResourceNotFoundError } from '@/restful/errors'; import { RequestInvalidError, ResourceNotFoundError } from '@/restful/errors';
import { formatDateTime } from '@/utils';
export default function register($app) { export default function register($app) {
if (!$.read(COLLECTIONS_KEY)) $.write({}, COLLECTIONS_KEY); if (!$.read(COLLECTIONS_KEY)) $.write({}, COLLECTIONS_KEY);
@ -60,20 +61,9 @@ function getCollection(req, res) {
.set( .set(
'content-disposition', 'content-disposition',
`attachment; filename="${encodeURIComponent( `attachment; filename="${encodeURIComponent(
`sub-store_collection_${name}_${new Date() `sub-store_collection_${name}_${formatDateTime(
.toLocaleString('zh-CN', { new Date(),
year: 'numeric', )}.json`,
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replace(
/^(\d+?)\/(\d+?)\/(\d+?)\s*?(\d+?):(\d+?):(\d+?)$/,
'$1-$2-$3_$4-$5-$6',
)}.json`,
)}"`, )}"`,
) )
.send(JSON.stringify(collection)); .send(JSON.stringify(collection));

View File

@ -9,6 +9,7 @@ import {
InternalServerError, InternalServerError,
} from '@/restful/errors'; } from '@/restful/errors';
import { produceArtifact } from '@/restful/sync'; import { produceArtifact } from '@/restful/sync';
import { formatDateTime } from '@/utils';
export default function register($app) { export default function register($app) {
if (!$.read(FILES_KEY)) $.write([], FILES_KEY); if (!$.read(FILES_KEY)) $.write([], FILES_KEY);
@ -210,20 +211,9 @@ function getWholeFile(req, res) {
.set( .set(
'content-disposition', 'content-disposition',
`attachment; filename="${encodeURIComponent( `attachment; filename="${encodeURIComponent(
`sub-store_file_${name}_${new Date() `sub-store_file_${name}_${formatDateTime(
.toLocaleString('zh-CN', { new Date(),
year: 'numeric', )}.json`,
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replace(
/^(\d+?)\/(\d+?)\/(\d+?)\s*?(\d+?):(\d+?):(\d+?)$/,
'$1-$2-$3_$4-$5-$6',
)}.json`,
)}"`, )}"`,
) )
.send(JSON.stringify(file)); .send(JSON.stringify(file));

View File

@ -14,6 +14,7 @@ import { InternalServerError, RequestInvalidError } from '@/restful/errors';
import Gist from '@/utils/gist'; import Gist from '@/utils/gist';
import migrate from '@/utils/migration'; import migrate from '@/utils/migration';
import env from '@/utils/env'; import env from '@/utils/env';
import { formatDateTime } from '@/utils';
export default function register($app) { export default function register($app) {
// utils // utils
@ -28,20 +29,7 @@ export default function register($app) {
.set( .set(
'content-disposition', 'content-disposition',
`attachment; filename="${encodeURIComponent( `attachment; filename="${encodeURIComponent(
`sub-store_data_${new Date() `sub-store_data_${formatDateTime(new Date())}.json`,
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replace(
/^(\d+?)\/(\d+?)\/(\d+?)\s*?(\d+?):(\d+?):(\d+?)$/,
'$1-$2-$3_$4-$5-$6',
)}.json`,
)}"`, )}"`,
) )
.send( .send(

View File

@ -13,6 +13,7 @@ import {
} from '@/utils/flow'; } from '@/utils/flow';
import { success, failed } from './response'; import { success, failed } from './response';
import $ from '@/core/app'; import $ from '@/core/app';
import { formatDateTime } from '@/utils';
if (!$.read(SUBS_KEY)) $.write({}, SUBS_KEY); if (!$.read(SUBS_KEY)) $.write({}, SUBS_KEY);
@ -265,20 +266,9 @@ function getSubscription(req, res) {
.set( .set(
'content-disposition', 'content-disposition',
`attachment; filename="${encodeURIComponent( `attachment; filename="${encodeURIComponent(
`sub-store_subscription_${name}_${new Date() `sub-store_subscription_${name}_${formatDateTime(
.toLocaleString('zh-CN', { new Date(),
year: 'numeric', )}.json`,
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replace(
/^(\d+?)\/(\d+?)\/(\d+?)\s*?(\d+?):(\d+?):(\d+?)$/,
'$1-$2-$3_$4-$5-$6',
)}.json`,
)}"`, )}"`,
) )
.send(JSON.stringify(sub)); .send(JSON.stringify(sub));

View File

@ -126,7 +126,32 @@ function isValidUUID(uuid) {
); );
} }
function formatDateTime(date, format = 'YYYY-MM-DD_HH-mm-ss') {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) {
return '';
}
const pad = (num) => String(num).padStart(2, '0');
const replacements = {
YYYY: d.getFullYear(),
MM: pad(d.getMonth() + 1),
DD: pad(d.getDate()),
HH: pad(d.getHours()),
mm: pad(d.getMinutes()),
ss: pad(d.getSeconds()),
};
return format.replace(
/YYYY|MM|DD|HH|mm|ss/g,
(match) => replacements[match],
);
}
export { export {
formatDateTime,
isValidUUID, isValidUUID,
ipAddress, ipAddress,
isIPv4, isIPv4,