sa2kit 1.6.29 → 1.6.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AliyunOSSProvider-P6TOVKMM.mjs +6 -0
- package/dist/{AliyunOSSProvider-I7I5YGLB.mjs.map → AliyunOSSProvider-P6TOVKMM.mjs.map} +1 -1
- package/dist/AliyunOSSProvider-Z5BRBCG6.js +15 -0
- package/dist/{AliyunOSSProvider-L7JWMKS4.js.map → AliyunOSSProvider-Z5BRBCG6.js.map} +1 -1
- package/dist/ConfigService-3DIC6C3Q.js +21 -0
- package/dist/{ConfigService-7MEZXKJ5.js.map → ConfigService-3DIC6C3Q.js.map} +1 -1
- package/dist/ConfigService-V6ZK273Z.mjs +4 -0
- package/dist/{ConfigService-BV57YYFW.mjs.map → ConfigService-V6ZK273Z.mjs.map} +1 -1
- package/dist/LocalStorageProvider-3RVPCQB3.mjs +6 -0
- package/dist/{LocalStorageProvider-FVLLHBHO.mjs.map → LocalStorageProvider-3RVPCQB3.mjs.map} +1 -1
- package/dist/LocalStorageProvider-PP7MA5OT.js +15 -0
- package/dist/{LocalStorageProvider-NBNHHWLY.js.map → LocalStorageProvider-PP7MA5OT.js.map} +1 -1
- package/dist/PMXParser-2VTA737I.js +13 -0
- package/dist/{PMXParser-YBS3B6HM.js.map → PMXParser-2VTA737I.js.map} +1 -1
- package/dist/PMXParser-RNVQL76A.mjs +4 -0
- package/dist/{PMXParser-L6IWHL4I.mjs.map → PMXParser-RNVQL76A.mjs.map} +1 -1
- package/dist/analytics/index.js +46 -45
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +45 -44
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/analytics/server/index.js +4 -4
- package/dist/analytics/server/index.js.map +1 -1
- package/dist/analytics/server/index.mjs +4 -4
- package/dist/analytics/server/index.mjs.map +1 -1
- package/dist/api/index.js +5 -5
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +5 -5
- package/dist/api/index.mjs.map +1 -1
- package/dist/audioDetection/index.js +17 -16
- package/dist/audioDetection/index.js.map +1 -1
- package/dist/audioDetection/index.mjs +17 -16
- package/dist/audioDetection/index.mjs.map +1 -1
- package/dist/auth/client/index.js +4 -4
- package/dist/auth/client/index.mjs +1 -1
- package/dist/auth/components/index.js +3 -3
- package/dist/auth/components/index.js.map +1 -1
- package/dist/auth/components/index.mjs +3 -3
- package/dist/auth/components/index.mjs.map +1 -1
- package/dist/auth/index.js +29 -29
- package/dist/auth/index.mjs +5 -5
- package/dist/auth/middleware/index.js +3 -3
- package/dist/auth/middleware/index.mjs +2 -2
- package/dist/auth/routes/index.js +14 -14
- package/dist/auth/routes/index.mjs +2 -2
- package/dist/auth/services/index.js +7 -7
- package/dist/auth/services/index.mjs +1 -1
- package/dist/calendar/index.js +146 -182
- package/dist/calendar/index.js.map +1 -1
- package/dist/calendar/index.mjs +139 -175
- package/dist/calendar/index.mjs.map +1 -1
- package/dist/calendar/routes/index.js +1 -1
- package/dist/calendar/routes/index.js.map +1 -1
- package/dist/calendar/routes/index.mjs +1 -1
- package/dist/calendar/routes/index.mjs.map +1 -1
- package/dist/{chunk-5YQ5B7IZ.js → chunk-24HGREE6.js} +5 -5
- package/dist/{chunk-5YQ5B7IZ.js.map → chunk-24HGREE6.js.map} +1 -1
- package/dist/{chunk-6PRFP5EG.js → chunk-25OFOKNF.js} +6 -6
- package/dist/chunk-25OFOKNF.js.map +1 -0
- package/dist/{chunk-KQGP6BTS.mjs → chunk-3DXPQ4YV.mjs} +6 -6
- package/dist/chunk-3DXPQ4YV.mjs.map +1 -0
- package/dist/{chunk-3BGPZN4X.mjs → chunk-3NHAT7D4.mjs} +12 -12
- package/dist/chunk-3NHAT7D4.mjs.map +1 -0
- package/dist/{chunk-MW4BCIZC.mjs → chunk-4HC6M7FK.mjs} +3 -3
- package/dist/chunk-4HC6M7FK.mjs.map +1 -0
- package/dist/{chunk-ESRCX5TQ.mjs → chunk-52TN2QSS.mjs} +3 -3
- package/dist/{chunk-ESRCX5TQ.mjs.map → chunk-52TN2QSS.mjs.map} +1 -1
- package/dist/{chunk-DW2ZTOCV.js → chunk-5A7ERLKK.js} +105 -106
- package/dist/chunk-5A7ERLKK.js.map +1 -0
- package/dist/{chunk-CNTILN5J.mjs → chunk-5YQ62BKX.mjs} +20 -19
- package/dist/chunk-5YQ62BKX.mjs.map +1 -0
- package/dist/{chunk-6W5BMXJG.js → chunk-6OWNMJKG.js} +4 -4
- package/dist/{chunk-6W5BMXJG.js.map → chunk-6OWNMJKG.js.map} +1 -1
- package/dist/{chunk-WSNM4EU5.mjs → chunk-77M5AQG3.mjs} +37 -41
- package/dist/chunk-77M5AQG3.mjs.map +1 -0
- package/dist/{chunk-DUHZ7VZP.js → chunk-7VRT55ZD.js} +3 -3
- package/dist/chunk-7VRT55ZD.js.map +1 -0
- package/dist/{chunk-LX4XX6W7.js → chunk-C54W2CMK.js} +16 -16
- package/dist/chunk-C54W2CMK.js.map +1 -0
- package/dist/{chunk-3WOAPLEG.mjs → chunk-EB4NR623.mjs} +27 -26
- package/dist/chunk-EB4NR623.mjs.map +1 -0
- package/dist/{chunk-CD77U7LZ.js → chunk-GBPLX42J.js} +9 -9
- package/dist/chunk-GBPLX42J.js.map +1 -0
- package/dist/{chunk-TFQF2HDO.mjs → chunk-HDEOCX2L.mjs} +12 -12
- package/dist/chunk-HDEOCX2L.mjs.map +1 -0
- package/dist/{chunk-LFG6FPM5.mjs → chunk-KIP2CERU.mjs} +37 -38
- package/dist/chunk-KIP2CERU.mjs.map +1 -0
- package/dist/{chunk-6YKMCPQI.mjs → chunk-KZKIH4AS.mjs} +4 -4
- package/dist/chunk-KZKIH4AS.mjs.map +1 -0
- package/dist/{chunk-6MQUBPKB.mjs → chunk-LJ4CCSSY.mjs} +3 -3
- package/dist/{chunk-6MQUBPKB.mjs.map → chunk-LJ4CCSSY.mjs.map} +1 -1
- package/dist/{chunk-TOC5FSHP.js → chunk-NJ2SNXBJ.js} +12 -12
- package/dist/chunk-NJ2SNXBJ.js.map +1 -0
- package/dist/{chunk-OCR5DS4C.mjs → chunk-PE5EAHZK.mjs} +3 -3
- package/dist/chunk-PE5EAHZK.mjs.map +1 -0
- package/dist/{chunk-TKCYPDWU.js → chunk-Q5EDCKQA.js} +27 -29
- package/dist/chunk-Q5EDCKQA.js.map +1 -0
- package/dist/{chunk-CLKKZSPZ.js → chunk-RBKGYWME.js} +20 -19
- package/dist/chunk-RBKGYWME.js.map +1 -0
- package/dist/{chunk-VRTRSEEH.mjs → chunk-RSJSZ7QH.mjs} +11 -11
- package/dist/chunk-RSJSZ7QH.mjs.map +1 -0
- package/dist/{chunk-E7RGBAYJ.js → chunk-TDCDEBGP.js} +30 -29
- package/dist/chunk-TDCDEBGP.js.map +1 -0
- package/dist/{chunk-T5OZHYVM.mjs → chunk-TVROG2Q4.mjs} +15 -15
- package/dist/chunk-TVROG2Q4.mjs.map +1 -0
- package/dist/{chunk-JZXJQMVE.js → chunk-UIFFDRTE.js} +11 -11
- package/dist/chunk-UIFFDRTE.js.map +1 -0
- package/dist/{chunk-UOFTHYIH.js → chunk-UL6XJGUZ.js} +4 -4
- package/dist/chunk-UL6XJGUZ.js.map +1 -0
- package/dist/{chunk-A3UP56MS.js → chunk-WA67GZSZ.js} +3 -3
- package/dist/chunk-WA67GZSZ.js.map +1 -0
- package/dist/{chunk-OLHGZXN3.mjs → chunk-WEEXCPSE.mjs} +5 -5
- package/dist/chunk-WEEXCPSE.mjs.map +1 -0
- package/dist/{chunk-5GCHAXY5.js → chunk-X3UU7JHT.js} +38 -42
- package/dist/chunk-X3UU7JHT.js.map +1 -0
- package/dist/{chunk-QU5OT4DF.js → chunk-XJ7ZAGC5.js} +5 -5
- package/dist/chunk-XJ7ZAGC5.js.map +1 -0
- package/dist/{chunk-GSTLV3MB.mjs → chunk-YOTQG4NP.mjs} +26 -28
- package/dist/chunk-YOTQG4NP.mjs.map +1 -0
- package/dist/{chunk-QAT2RWAO.mjs → chunk-Z36R3P62.mjs} +7 -7
- package/dist/chunk-Z36R3P62.mjs.map +1 -0
- package/dist/{chunk-7Z5LLJ3A.js → chunk-ZWQJSZEY.js} +13 -13
- package/dist/chunk-ZWQJSZEY.js.map +1 -0
- package/dist/config/index.js +6 -6
- package/dist/config/index.js.map +1 -1
- package/dist/config/index.mjs +6 -6
- package/dist/config/index.mjs.map +1 -1
- package/dist/config/server/index.js +37 -37
- package/dist/config/server/index.js.map +1 -1
- package/dist/config/server/index.mjs +37 -37
- package/dist/config/server/index.mjs.map +1 -1
- package/dist/i18n/index.d.mts +2 -2
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +16 -17
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/index.mjs +16 -17
- package/dist/i18n/index.mjs.map +1 -1
- package/dist/imageCrop/index.js +11 -10
- package/dist/imageCrop/index.js.map +1 -1
- package/dist/imageCrop/index.mjs +11 -10
- package/dist/imageCrop/index.mjs.map +1 -1
- package/dist/index.js +221 -246
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -104
- package/dist/index.mjs.map +1 -1
- package/dist/logger/index.js +6 -6
- package/dist/logger/index.mjs +1 -1
- package/dist/mmd/admin/index.js +11 -10
- package/dist/mmd/admin/index.js.map +1 -1
- package/dist/mmd/admin/index.mjs +11 -10
- package/dist/mmd/admin/index.mjs.map +1 -1
- package/dist/mmd/index.js +223 -241
- package/dist/mmd/index.js.map +1 -1
- package/dist/mmd/index.mjs +220 -238
- package/dist/mmd/index.mjs.map +1 -1
- package/dist/mmd/server/index.js +6 -6
- package/dist/mmd/server/index.js.map +1 -1
- package/dist/mmd/server/index.mjs +6 -6
- package/dist/mmd/server/index.mjs.map +1 -1
- package/dist/music/index.js +16 -16
- package/dist/music/index.mjs +2 -2
- package/dist/music/server/index.js +8 -8
- package/dist/music/server/index.mjs +1 -1
- package/dist/request/index.js +2 -2
- package/dist/request/index.js.map +1 -1
- package/dist/request/index.mjs +2 -2
- package/dist/request/index.mjs.map +1 -1
- package/dist/storage/index.js +11 -11
- package/dist/storage/index.mjs +2 -2
- package/dist/testYourself/admin/index.js +3 -3
- package/dist/testYourself/admin/index.mjs +1 -1
- package/dist/testYourself/index.js +22 -22
- package/dist/testYourself/index.js.map +1 -1
- package/dist/testYourself/index.mjs +14 -14
- package/dist/testYourself/index.mjs.map +1 -1
- package/dist/testYourself/server/index.js +4 -4
- package/dist/testYourself/server/index.mjs +1 -1
- package/dist/universalExport/index.d.mts +3 -3
- package/dist/universalExport/index.d.ts +3 -3
- package/dist/universalExport/index.js +48 -47
- package/dist/universalExport/index.js.map +1 -1
- package/dist/universalExport/index.mjs +48 -47
- package/dist/universalExport/index.mjs.map +1 -1
- package/dist/universalExport/server/index.js +29 -29
- package/dist/universalExport/server/index.js.map +1 -1
- package/dist/universalExport/server/index.mjs +28 -28
- package/dist/universalExport/server/index.mjs.map +1 -1
- package/dist/universalFile/index.d.mts +3 -3
- package/dist/universalFile/index.d.ts +3 -3
- package/dist/universalFile/index.js +73 -72
- package/dist/universalFile/index.js.map +1 -1
- package/dist/universalFile/index.mjs +73 -72
- package/dist/universalFile/index.mjs.map +1 -1
- package/dist/universalFile/server/index.js +258 -260
- package/dist/universalFile/server/index.js.map +1 -1
- package/dist/universalFile/server/index.mjs +244 -246
- package/dist/universalFile/server/index.mjs.map +1 -1
- package/dist/utils/index.js +11 -11
- package/dist/utils/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/AliyunOSSProvider-I7I5YGLB.mjs +0 -6
- package/dist/AliyunOSSProvider-L7JWMKS4.js +0 -15
- package/dist/ConfigService-7MEZXKJ5.js +0 -21
- package/dist/ConfigService-BV57YYFW.mjs +0 -4
- package/dist/LocalStorageProvider-FVLLHBHO.mjs +0 -6
- package/dist/LocalStorageProvider-NBNHHWLY.js +0 -15
- package/dist/PMXParser-L6IWHL4I.mjs +0 -4
- package/dist/PMXParser-YBS3B6HM.js +0 -13
- package/dist/chunk-3BGPZN4X.mjs.map +0 -1
- package/dist/chunk-3WOAPLEG.mjs.map +0 -1
- package/dist/chunk-5GCHAXY5.js.map +0 -1
- package/dist/chunk-6PRFP5EG.js.map +0 -1
- package/dist/chunk-6YKMCPQI.mjs.map +0 -1
- package/dist/chunk-7Z5LLJ3A.js.map +0 -1
- package/dist/chunk-A3UP56MS.js.map +0 -1
- package/dist/chunk-CD77U7LZ.js.map +0 -1
- package/dist/chunk-CLKKZSPZ.js.map +0 -1
- package/dist/chunk-CNTILN5J.mjs.map +0 -1
- package/dist/chunk-DUHZ7VZP.js.map +0 -1
- package/dist/chunk-DW2ZTOCV.js.map +0 -1
- package/dist/chunk-E7RGBAYJ.js.map +0 -1
- package/dist/chunk-GSTLV3MB.mjs.map +0 -1
- package/dist/chunk-JZXJQMVE.js.map +0 -1
- package/dist/chunk-KQGP6BTS.mjs.map +0 -1
- package/dist/chunk-LFG6FPM5.mjs.map +0 -1
- package/dist/chunk-LX4XX6W7.js.map +0 -1
- package/dist/chunk-MW4BCIZC.mjs.map +0 -1
- package/dist/chunk-OCR5DS4C.mjs.map +0 -1
- package/dist/chunk-OLHGZXN3.mjs.map +0 -1
- package/dist/chunk-QAT2RWAO.mjs.map +0 -1
- package/dist/chunk-QU5OT4DF.js.map +0 -1
- package/dist/chunk-T5OZHYVM.mjs.map +0 -1
- package/dist/chunk-TFQF2HDO.mjs.map +0 -1
- package/dist/chunk-TKCYPDWU.js.map +0 -1
- package/dist/chunk-TOC5FSHP.js.map +0 -1
- package/dist/chunk-UOFTHYIH.js.map +0 -1
- package/dist/chunk-VRTRSEEH.mjs.map +0 -1
- package/dist/chunk-WSNM4EU5.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { LocalStorageProvider } from '../../chunk-
|
|
2
|
-
export { AliyunOSSProvider } from '../../chunk-
|
|
1
|
+
export { LocalStorageProvider } from '../../chunk-YOTQG4NP.mjs';
|
|
2
|
+
export { AliyunOSSProvider } from '../../chunk-77M5AQG3.mjs';
|
|
3
3
|
import { CDNProviderError } from '../../chunk-ZGVB35L2.mjs';
|
|
4
|
-
import { createLogger } from '../../chunk-
|
|
4
|
+
import { createLogger } from '../../chunk-3DXPQ4YV.mjs';
|
|
5
5
|
import { StorageProviderError, FileUploadError, FileProcessingError } from '../../chunk-CIVO4R6N.mjs';
|
|
6
6
|
import { __require } from '../../chunk-BJTO5JO5.mjs';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
@@ -88,7 +88,7 @@ function createFileServiceFromEnv(db) {
|
|
|
88
88
|
};
|
|
89
89
|
break;
|
|
90
90
|
default:
|
|
91
|
-
throw new Error(
|
|
91
|
+
throw new Error("Unsupported storage type: " + storageType);
|
|
92
92
|
}
|
|
93
93
|
return createUniversalFileService({
|
|
94
94
|
storage,
|
|
@@ -221,7 +221,7 @@ function validateStorageConfig(storage) {
|
|
|
221
221
|
}
|
|
222
222
|
default:
|
|
223
223
|
throw new ConfigValidationError(
|
|
224
|
-
|
|
224
|
+
"Unsupported storage type: " + storage.type,
|
|
225
225
|
"storage.type"
|
|
226
226
|
);
|
|
227
227
|
}
|
|
@@ -253,7 +253,7 @@ function validateEnvironment(requiredVars) {
|
|
|
253
253
|
}
|
|
254
254
|
if (missing.length > 0) {
|
|
255
255
|
throw new ConfigValidationError(
|
|
256
|
-
|
|
256
|
+
"Missing required environment variables: " + missing.join(", "),
|
|
257
257
|
"environment"
|
|
258
258
|
);
|
|
259
259
|
}
|
|
@@ -289,7 +289,7 @@ var AliyunCDNProvider = class {
|
|
|
289
289
|
throw new CDNProviderError("\u914D\u7F6E\u7C7B\u578B\u4E0D\u5339\u914D\uFF1A\u671F\u671B aliyun-cdn");
|
|
290
290
|
}
|
|
291
291
|
this.config = config;
|
|
292
|
-
logger.info(
|
|
292
|
+
logger.info("\u{1F310} [AliyunCDNProvider] \u521D\u59CB\u5316\u963F\u91CC\u4E91CDN\uFF0C\u57DF\u540D: " + this.config.domain);
|
|
293
293
|
try {
|
|
294
294
|
this.validateConfig();
|
|
295
295
|
try {
|
|
@@ -311,7 +311,7 @@ var AliyunCDNProvider = class {
|
|
|
311
311
|
} catch (error) {
|
|
312
312
|
logger.error("\u274C [AliyunCDNProvider] \u963F\u91CC\u4E91CDN\u521D\u59CB\u5316\u5931\u8D25:", error);
|
|
313
313
|
throw new CDNProviderError(
|
|
314
|
-
|
|
314
|
+
"\u963F\u91CC\u4E91CDN\u521D\u59CB\u5316\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
315
315
|
);
|
|
316
316
|
}
|
|
317
317
|
}
|
|
@@ -320,16 +320,16 @@ var AliyunCDNProvider = class {
|
|
|
320
320
|
*/
|
|
321
321
|
async generateUrl(originalUrl) {
|
|
322
322
|
this.ensureInitialized();
|
|
323
|
-
logger.info(
|
|
323
|
+
logger.info("\u{1F517} [AliyunCDNProvider] \u751F\u6210CDN URL: " + originalUrl);
|
|
324
324
|
try {
|
|
325
325
|
const url = new URL(originalUrl);
|
|
326
|
-
const cdnUrl =
|
|
327
|
-
logger.info(
|
|
326
|
+
const cdnUrl = url.protocol + "//" + this.config.domain + url.pathname + url.search + url.hash;
|
|
327
|
+
logger.info("\u2705 [AliyunCDNProvider] CDN URL\u751F\u6210\u5B8C\u6210: " + cdnUrl);
|
|
328
328
|
return cdnUrl;
|
|
329
329
|
} catch (error) {
|
|
330
|
-
logger.error(
|
|
330
|
+
logger.error("\u274C [AliyunCDNProvider] CDN URL\u751F\u6210\u5931\u8D25: " + originalUrl + ":", error);
|
|
331
331
|
throw new CDNProviderError(
|
|
332
|
-
|
|
332
|
+
"CDN URL\u751F\u6210\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
333
333
|
);
|
|
334
334
|
}
|
|
335
335
|
}
|
|
@@ -338,7 +338,7 @@ var AliyunCDNProvider = class {
|
|
|
338
338
|
*/
|
|
339
339
|
async refreshCache(urls) {
|
|
340
340
|
this.ensureInitialized();
|
|
341
|
-
logger.info(
|
|
341
|
+
logger.info("\u{1F504} [AliyunCDNProvider] \u5F00\u59CB\u5237\u65B0CDN\u7F13\u5B58\uFF0CURL\u6570\u91CF: " + urls.length);
|
|
342
342
|
try {
|
|
343
343
|
const cdnUrls = await Promise.all(urls.map((url) => this.generateUrl(url)));
|
|
344
344
|
const result = await this.client.refreshObjectCaches({
|
|
@@ -348,7 +348,7 @@ var AliyunCDNProvider = class {
|
|
|
348
348
|
// File 或 Directory
|
|
349
349
|
});
|
|
350
350
|
logger.info(
|
|
351
|
-
|
|
351
|
+
"\u2705 [AliyunCDNProvider] CDN\u7F13\u5B58\u5237\u65B0\u5B8C\u6210\uFF0C\u4EFB\u52A1ID: " + (result.RefreshTaskId || "unknown")
|
|
352
352
|
);
|
|
353
353
|
return {
|
|
354
354
|
success: true,
|
|
@@ -362,7 +362,7 @@ var AliyunCDNProvider = class {
|
|
|
362
362
|
logger.error(`\u274C [AliyunCDNProvider] CDN\u7F13\u5B58\u5237\u65B0\u5931\u8D25:`, error);
|
|
363
363
|
return {
|
|
364
364
|
success: false,
|
|
365
|
-
error:
|
|
365
|
+
error: "CDN\u7F13\u5B58\u5237\u65B0\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
366
366
|
};
|
|
367
367
|
}
|
|
368
368
|
}
|
|
@@ -371,7 +371,7 @@ var AliyunCDNProvider = class {
|
|
|
371
371
|
*/
|
|
372
372
|
async preheatCache(urls) {
|
|
373
373
|
this.ensureInitialized();
|
|
374
|
-
logger.info(
|
|
374
|
+
logger.info("\u{1F525} [AliyunCDNProvider] \u5F00\u59CB\u9884\u70EDCDN\u7F13\u5B58\uFF0CURL\u6570\u91CF: " + urls.length);
|
|
375
375
|
try {
|
|
376
376
|
const cdnUrls = await Promise.all(urls.map((url) => this.generateUrl(url)));
|
|
377
377
|
const result = await this.client.pushObjectCache({
|
|
@@ -381,7 +381,7 @@ var AliyunCDNProvider = class {
|
|
|
381
381
|
// domestic, overseas, global
|
|
382
382
|
});
|
|
383
383
|
logger.info(
|
|
384
|
-
|
|
384
|
+
"\u2705 [AliyunCDNProvider] CDN\u7F13\u5B58\u9884\u70ED\u5B8C\u6210\uFF0C\u4EFB\u52A1ID: " + (result.PushTaskId || "unknown")
|
|
385
385
|
);
|
|
386
386
|
return {
|
|
387
387
|
success: true,
|
|
@@ -395,7 +395,7 @@ var AliyunCDNProvider = class {
|
|
|
395
395
|
logger.error(`\u274C [AliyunCDNProvider] CDN\u7F13\u5B58\u9884\u70ED\u5931\u8D25:`, error);
|
|
396
396
|
return {
|
|
397
397
|
success: false,
|
|
398
|
-
error:
|
|
398
|
+
error: "CDN\u7F13\u5B58\u9884\u70ED\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
399
399
|
};
|
|
400
400
|
}
|
|
401
401
|
}
|
|
@@ -405,7 +405,7 @@ var AliyunCDNProvider = class {
|
|
|
405
405
|
async getAccessStats(startTime, endTime) {
|
|
406
406
|
this.ensureInitialized();
|
|
407
407
|
logger.info(
|
|
408
|
-
|
|
408
|
+
"\u{1F4CA} [AliyunCDNProvider] \u83B7\u53D6CDN\u8BBF\u95EE\u7EDF\u8BA1: " + startTime.toISOString() + " - " + endTime.toISOString()
|
|
409
409
|
);
|
|
410
410
|
try {
|
|
411
411
|
const formatTime = (date) => date.toISOString().slice(0, 19).replace("T", " ") + "Z";
|
|
@@ -432,7 +432,7 @@ var AliyunCDNProvider = class {
|
|
|
432
432
|
logger.error(`\u274C [AliyunCDNProvider] CDN\u8BBF\u95EE\u7EDF\u8BA1\u83B7\u53D6\u5931\u8D25:`, error);
|
|
433
433
|
return {
|
|
434
434
|
success: false,
|
|
435
|
-
error:
|
|
435
|
+
error: "CDN\u8BBF\u95EE\u7EDF\u8BA1\u83B7\u53D6\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
438
|
}
|
|
@@ -442,7 +442,7 @@ var AliyunCDNProvider = class {
|
|
|
442
442
|
*/
|
|
443
443
|
async generateSignedUrl(originalUrl, expiresIn = 3600, authKey) {
|
|
444
444
|
this.ensureInitialized();
|
|
445
|
-
logger.info(
|
|
445
|
+
logger.info("\u{1F510} [AliyunCDNProvider] \u751F\u6210\u9632\u76D7\u94FE\u7B7E\u540DURL: " + originalUrl);
|
|
446
446
|
try {
|
|
447
447
|
const cdnUrl = await this.generateUrl(originalUrl);
|
|
448
448
|
if (!authKey) {
|
|
@@ -451,15 +451,15 @@ var AliyunCDNProvider = class {
|
|
|
451
451
|
}
|
|
452
452
|
const parsedUrl = new URL(cdnUrl);
|
|
453
453
|
const timestamp2 = Math.floor(Date.now() / 1e3) + expiresIn;
|
|
454
|
-
const signString =
|
|
454
|
+
const signString = parsedUrl.pathname + "-" + timestamp2 + "-0-0-" + authKey;
|
|
455
455
|
const authValue = createHash("md5").update(signString).digest("hex");
|
|
456
|
-
const signedUrl =
|
|
456
|
+
const signedUrl = cdnUrl + "?auth_key=" + timestamp2 + "-0-0-" + authValue;
|
|
457
457
|
logger.info(`\u2705 [AliyunCDNProvider] \u9632\u76D7\u94FE\u7B7E\u540DURL\u751F\u6210\u5B8C\u6210`);
|
|
458
458
|
return signedUrl;
|
|
459
459
|
} catch (error) {
|
|
460
|
-
logger.error(
|
|
460
|
+
logger.error("\u274C [AliyunCDNProvider] \u9632\u76D7\u94FE\u7B7E\u540DURL\u751F\u6210\u5931\u8D25: " + originalUrl + ":", error);
|
|
461
461
|
throw new CDNProviderError(
|
|
462
|
-
|
|
462
|
+
"\u9632\u76D7\u94FE\u7B7E\u540DURL\u751F\u6210\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
463
463
|
);
|
|
464
464
|
}
|
|
465
465
|
}
|
|
@@ -482,7 +482,7 @@ var AliyunCDNProvider = class {
|
|
|
482
482
|
} catch (error) {
|
|
483
483
|
return {
|
|
484
484
|
success: false,
|
|
485
|
-
error:
|
|
485
|
+
error: "\u67E5\u8BE2\u5237\u65B0\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
486
486
|
};
|
|
487
487
|
}
|
|
488
488
|
}
|
|
@@ -505,7 +505,7 @@ var AliyunCDNProvider = class {
|
|
|
505
505
|
} catch (error) {
|
|
506
506
|
return {
|
|
507
507
|
success: false,
|
|
508
|
-
error:
|
|
508
|
+
error: "\u67E5\u8BE2\u9884\u70ED\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
509
509
|
};
|
|
510
510
|
}
|
|
511
511
|
}
|
|
@@ -528,7 +528,7 @@ var AliyunCDNProvider = class {
|
|
|
528
528
|
} catch (error) {
|
|
529
529
|
return {
|
|
530
530
|
success: false,
|
|
531
|
-
error:
|
|
531
|
+
error: "\u83B7\u53D6\u57DF\u540D\u914D\u7F6E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
532
532
|
};
|
|
533
533
|
}
|
|
534
534
|
}
|
|
@@ -542,23 +542,23 @@ var AliyunCDNProvider = class {
|
|
|
542
542
|
const url = new URL(cdnUrl);
|
|
543
543
|
const params = new URLSearchParams(url.search);
|
|
544
544
|
if (options.imageQuality) {
|
|
545
|
-
params.set("x-oss-process",
|
|
545
|
+
params.set("x-oss-process", "image/quality,q_" + options.imageQuality);
|
|
546
546
|
}
|
|
547
547
|
if (options.imageFormat) {
|
|
548
548
|
const formatParam = params.get("x-oss-process") || "image";
|
|
549
|
-
params.set("x-oss-process",
|
|
549
|
+
params.set("x-oss-process", formatParam + "/format," + options.imageFormat);
|
|
550
550
|
}
|
|
551
551
|
if (options.imageResize) {
|
|
552
552
|
const resizeParam = params.get("x-oss-process") || "image";
|
|
553
553
|
let resize = "resize";
|
|
554
|
-
if (options.imageResize.width) resize +=
|
|
555
|
-
if (options.imageResize.height) resize +=
|
|
556
|
-
params.set("x-oss-process",
|
|
554
|
+
if (options.imageResize.width) resize += ",w_" + options.imageResize.width;
|
|
555
|
+
if (options.imageResize.height) resize += ",h_" + options.imageResize.height;
|
|
556
|
+
params.set("x-oss-process", resizeParam + "/" + resize);
|
|
557
557
|
}
|
|
558
558
|
url.search = params.toString();
|
|
559
559
|
return url.toString();
|
|
560
560
|
} catch (error) {
|
|
561
|
-
logger.error(
|
|
561
|
+
logger.error("\u274C [AliyunCDNProvider] URL\u4F18\u5316\u5931\u8D25: " + originalUrl + ":", error);
|
|
562
562
|
return this.generateUrl(originalUrl);
|
|
563
563
|
}
|
|
564
564
|
}
|
|
@@ -581,10 +581,10 @@ var AliyunCDNProvider = class {
|
|
|
581
581
|
const required = ["domain", "accessKeyId", "accessKeySecret"];
|
|
582
582
|
const missing = required.filter((key) => !this.config[key]);
|
|
583
583
|
if (missing.length > 0) {
|
|
584
|
-
throw new CDNProviderError(
|
|
584
|
+
throw new CDNProviderError("CDN\u914D\u7F6E\u7F3A\u5C11\u5FC5\u9700\u9879: " + missing.join(", "));
|
|
585
585
|
}
|
|
586
586
|
if (!this.isValidDomain(this.config.domain)) {
|
|
587
|
-
throw new CDNProviderError(
|
|
587
|
+
throw new CDNProviderError("\u65E0\u6548\u7684CDN\u57DF\u540D: " + this.config.domain);
|
|
588
588
|
}
|
|
589
589
|
}
|
|
590
590
|
/**
|
|
@@ -614,15 +614,15 @@ var AliyunCDNProvider = class {
|
|
|
614
614
|
async refreshObjectCaches(params) {
|
|
615
615
|
logger.info("\u{1F504} [MockCDN] \u6A21\u62DF\u5237\u65B0\u7F13\u5B58:", params);
|
|
616
616
|
return {
|
|
617
|
-
RefreshTaskId:
|
|
618
|
-
RequestId:
|
|
617
|
+
RefreshTaskId: "mock-refresh-" + Date.now(),
|
|
618
|
+
RequestId: "mock-request-" + Date.now()
|
|
619
619
|
};
|
|
620
620
|
},
|
|
621
621
|
async pushObjectCache(params) {
|
|
622
622
|
logger.info("\u{1F525} [MockCDN] \u6A21\u62DF\u9884\u70ED\u7F13\u5B58:", params);
|
|
623
623
|
return {
|
|
624
|
-
PushTaskId:
|
|
625
|
-
RequestId:
|
|
624
|
+
PushTaskId: "mock-push-" + Date.now(),
|
|
625
|
+
RequestId: "mock-request-" + Date.now()
|
|
626
626
|
};
|
|
627
627
|
},
|
|
628
628
|
async describeRefreshTasks(params) {
|
|
@@ -638,7 +638,7 @@ var AliyunCDNProvider = class {
|
|
|
638
638
|
}
|
|
639
639
|
]
|
|
640
640
|
},
|
|
641
|
-
RequestId:
|
|
641
|
+
RequestId: "mock-request-" + Date.now()
|
|
642
642
|
};
|
|
643
643
|
},
|
|
644
644
|
async describePushTasks(params) {
|
|
@@ -654,7 +654,7 @@ var AliyunCDNProvider = class {
|
|
|
654
654
|
}
|
|
655
655
|
]
|
|
656
656
|
},
|
|
657
|
-
RequestId:
|
|
657
|
+
RequestId: "mock-request-" + Date.now()
|
|
658
658
|
};
|
|
659
659
|
},
|
|
660
660
|
async describeDomainConfigs(params) {
|
|
@@ -669,7 +669,7 @@ var AliyunCDNProvider = class {
|
|
|
669
669
|
}
|
|
670
670
|
]
|
|
671
671
|
},
|
|
672
|
-
RequestId:
|
|
672
|
+
RequestId: "mock-request-" + Date.now()
|
|
673
673
|
};
|
|
674
674
|
},
|
|
675
675
|
async describeCdnDomainLogs(params) {
|
|
@@ -678,7 +678,7 @@ var AliyunCDNProvider = class {
|
|
|
678
678
|
DomainLogDetails: {
|
|
679
679
|
DomainLogDetail: []
|
|
680
680
|
},
|
|
681
|
-
RequestId:
|
|
681
|
+
RequestId: "mock-request-" + Date.now()
|
|
682
682
|
};
|
|
683
683
|
},
|
|
684
684
|
async describeDomainRealTimeData(params) {
|
|
@@ -693,7 +693,7 @@ var AliyunCDNProvider = class {
|
|
|
693
693
|
]
|
|
694
694
|
},
|
|
695
695
|
DataInterval: "60",
|
|
696
|
-
RequestId:
|
|
696
|
+
RequestId: "mock-request-" + Date.now()
|
|
697
697
|
};
|
|
698
698
|
}
|
|
699
699
|
};
|
|
@@ -704,7 +704,7 @@ var AliyunCDNProvider = class {
|
|
|
704
704
|
async batchRefreshCache(urls, batchSize = 20, onProgress) {
|
|
705
705
|
this.ensureInitialized();
|
|
706
706
|
logger.info(
|
|
707
|
-
|
|
707
|
+
"\u{1F504} [AliyunCDNProvider] \u5F00\u59CB\u6279\u91CF\u5237\u65B0\u7F13\u5B58\uFF0C\u603BURL\u6570: " + urls.length + "\uFF0C\u6279\u6B21\u5927\u5C0F: " + batchSize
|
|
708
708
|
);
|
|
709
709
|
try {
|
|
710
710
|
const results = [];
|
|
@@ -722,7 +722,7 @@ var AliyunCDNProvider = class {
|
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
724
|
const successCount = results.filter((r) => r.success).length;
|
|
725
|
-
logger.info(
|
|
725
|
+
logger.info("\u2705 [AliyunCDNProvider] \u6279\u91CF\u5237\u65B0\u5B8C\u6210\uFF0C\u6210\u529F: " + successCount + "/" + results.length);
|
|
726
726
|
return {
|
|
727
727
|
success: successCount === results.length,
|
|
728
728
|
data: {
|
|
@@ -735,7 +735,7 @@ var AliyunCDNProvider = class {
|
|
|
735
735
|
logger.error(`\u274C [AliyunCDNProvider] \u6279\u91CF\u5237\u65B0\u5931\u8D25:`, error);
|
|
736
736
|
return {
|
|
737
737
|
success: false,
|
|
738
|
-
error:
|
|
738
|
+
error: "\u6279\u91CF\u5237\u65B0\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
739
739
|
};
|
|
740
740
|
}
|
|
741
741
|
}
|
|
@@ -945,7 +945,7 @@ var CdnCacheStrategy = class {
|
|
|
945
945
|
Expires: new Date(Date.now() + strategy.browserCacheTtl * 1e3).toUTCString()
|
|
946
946
|
};
|
|
947
947
|
if (strategy.browserCache) {
|
|
948
|
-
headers["ETag"] =
|
|
948
|
+
headers["ETag"] = '"' + Date.now() + '"';
|
|
949
949
|
}
|
|
950
950
|
headers["Last-Modified"] = (/* @__PURE__ */ new Date()).toUTCString();
|
|
951
951
|
if (strategy.type === "static" /* STATIC */) {
|
|
@@ -1024,7 +1024,7 @@ var CdnCacheStrategy = class {
|
|
|
1024
1024
|
if (stats.hitRate < 60) {
|
|
1025
1025
|
suggestions.push({
|
|
1026
1026
|
type,
|
|
1027
|
-
issue:
|
|
1027
|
+
issue: type + "\u7C7B\u578B\u6587\u4EF6\u7F13\u5B58\u547D\u4E2D\u7387\u8FC7\u4F4E (" + stats.hitRate.toFixed(1) + "%)",
|
|
1028
1028
|
suggestion: "\u8003\u8651\u589E\u52A0\u7F13\u5B58\u65F6\u95F4\u6216\u542F\u7528\u9884\u70ED\u673A\u5236",
|
|
1029
1029
|
severity: stats.hitRate < 30 ? "high" : "medium"
|
|
1030
1030
|
});
|
|
@@ -1032,7 +1032,7 @@ var CdnCacheStrategy = class {
|
|
|
1032
1032
|
if (stats.estimatedSize > 1024 * 1024 * 1024) {
|
|
1033
1033
|
suggestions.push({
|
|
1034
1034
|
type,
|
|
1035
|
-
issue:
|
|
1035
|
+
issue: type + "\u7C7B\u578B\u6587\u4EF6\u7F13\u5B58\u5360\u7528\u7A7A\u95F4\u8FC7\u5927 (" + (stats.estimatedSize / 1024 / 1024 / 1024).toFixed(2) + "GB)",
|
|
1036
1036
|
suggestion: "\u8003\u8651\u51CF\u5C11\u7F13\u5B58\u65F6\u95F4\u6216\u4F18\u5316\u6587\u4EF6\u538B\u7F29",
|
|
1037
1037
|
severity: "medium"
|
|
1038
1038
|
});
|
|
@@ -1104,16 +1104,16 @@ var ImageProcessor = class {
|
|
|
1104
1104
|
}
|
|
1105
1105
|
const imageOptions = options;
|
|
1106
1106
|
const startTime = Date.now();
|
|
1107
|
-
logger2.info(
|
|
1107
|
+
logger2.info("\u{1F5BC}\uFE0F [ImageProcessor] \u5F00\u59CB\u5904\u7406\u56FE\u7247: " + inputPath);
|
|
1108
1108
|
try {
|
|
1109
1109
|
if (!existsSync(inputPath)) {
|
|
1110
|
-
throw new Error(
|
|
1110
|
+
throw new Error("\u8F93\u5165\u6587\u4EF6\u4E0D\u5B58\u5728: " + inputPath);
|
|
1111
1111
|
}
|
|
1112
1112
|
const outputDir = path3.dirname(outputPath);
|
|
1113
1113
|
await promises.mkdir(outputDir, { recursive: true });
|
|
1114
1114
|
const metadata = await this.getImageMetadata(inputPath);
|
|
1115
1115
|
logger2.info(
|
|
1116
|
-
|
|
1116
|
+
"\u{1F4CA} [ImageProcessor] \u56FE\u7247\u4FE1\u606F: " + metadata.width + "x" + metadata.height + ", \u683C\u5F0F: " + metadata.format
|
|
1117
1117
|
);
|
|
1118
1118
|
let sharpInstance = this.sharp(inputPath);
|
|
1119
1119
|
sharpInstance = await this.applyImageOperations(sharpInstance, imageOptions);
|
|
@@ -1125,7 +1125,7 @@ var ImageProcessor = class {
|
|
|
1125
1125
|
thumbnailPath = await this.generateThumbnail(inputPath, outputPath, imageOptions);
|
|
1126
1126
|
}
|
|
1127
1127
|
const processingTime = Date.now() - startTime;
|
|
1128
|
-
logger2.info(
|
|
1128
|
+
logger2.info("\u2705 [ImageProcessor] \u56FE\u7247\u5904\u7406\u5B8C\u6210: " + outputPath + ", \u8017\u65F6: " + processingTime + "ms");
|
|
1129
1129
|
return {
|
|
1130
1130
|
success: true,
|
|
1131
1131
|
processedPath: outputPath,
|
|
@@ -1147,10 +1147,10 @@ var ImageProcessor = class {
|
|
|
1147
1147
|
}
|
|
1148
1148
|
};
|
|
1149
1149
|
} catch (error) {
|
|
1150
|
-
console.error(
|
|
1150
|
+
console.error("\u274C [ImageProcessor] \u56FE\u7247\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
1151
1151
|
return {
|
|
1152
1152
|
success: false,
|
|
1153
|
-
error:
|
|
1153
|
+
error: "\u56FE\u7247\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
|
|
1154
1154
|
processingTime: Date.now() - startTime
|
|
1155
1155
|
};
|
|
1156
1156
|
}
|
|
@@ -1194,7 +1194,7 @@ var ImageProcessor = class {
|
|
|
1194
1194
|
megapixels: metadata.width * metadata.height / 1e6
|
|
1195
1195
|
};
|
|
1196
1196
|
} catch (error) {
|
|
1197
|
-
console.error(
|
|
1197
|
+
console.error("\u274C [ImageProcessor] \u83B7\u53D6\u56FE\u7247\u4FE1\u606F\u5931\u8D25: " + filePath + ":", error);
|
|
1198
1198
|
throw error;
|
|
1199
1199
|
}
|
|
1200
1200
|
}
|
|
@@ -1223,8 +1223,8 @@ var ImageProcessor = class {
|
|
|
1223
1223
|
orientation: metadata.orientation
|
|
1224
1224
|
};
|
|
1225
1225
|
} catch (error) {
|
|
1226
|
-
console.error(
|
|
1227
|
-
throw new Error(
|
|
1226
|
+
console.error("\u274C [ImageProcessor] \u83B7\u53D6\u56FE\u7247\u5143\u6570\u636E\u5931\u8D25: " + filePath + ":", error);
|
|
1227
|
+
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u56FE\u7247\u5143\u6570\u636E: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"));
|
|
1228
1228
|
}
|
|
1229
1229
|
}
|
|
1230
1230
|
/**
|
|
@@ -1242,7 +1242,7 @@ var ImageProcessor = class {
|
|
|
1242
1242
|
};
|
|
1243
1243
|
sharpInstance = sharpInstance.resize(resizeOptions);
|
|
1244
1244
|
logger2.info(
|
|
1245
|
-
|
|
1245
|
+
"\u{1F527} [ImageProcessor] \u5E94\u7528\u5C3A\u5BF8\u8C03\u6574: " + (options.width || "auto") + "x" + (options.height || "auto")
|
|
1246
1246
|
);
|
|
1247
1247
|
}
|
|
1248
1248
|
sharpInstance = sharpInstance.rotate();
|
|
@@ -1257,7 +1257,7 @@ var ImageProcessor = class {
|
|
|
1257
1257
|
async applyWatermark(sharpInstance, watermarkOptions) {
|
|
1258
1258
|
try {
|
|
1259
1259
|
if (watermarkOptions.text) {
|
|
1260
|
-
logger2.info(
|
|
1260
|
+
logger2.info("\u{1F4A7} [ImageProcessor] \u5E94\u7528\u6587\u5B57\u6C34\u5370: " + watermarkOptions.text);
|
|
1261
1261
|
const textSvg = this.createTextWatermarkSvg(
|
|
1262
1262
|
watermarkOptions.text,
|
|
1263
1263
|
watermarkOptions.opacity || 0.5
|
|
@@ -1270,7 +1270,7 @@ var ImageProcessor = class {
|
|
|
1270
1270
|
}
|
|
1271
1271
|
]);
|
|
1272
1272
|
} else if (watermarkOptions.image && existsSync(watermarkOptions.image)) {
|
|
1273
|
-
logger2.info(
|
|
1273
|
+
logger2.info("\u{1F4A7} [ImageProcessor] \u5E94\u7528\u56FE\u7247\u6C34\u5370: " + watermarkOptions.image);
|
|
1274
1274
|
let watermarkBuffer = await promises.readFile(watermarkOptions.image);
|
|
1275
1275
|
if (watermarkOptions.opacity && watermarkOptions.opacity < 1) {
|
|
1276
1276
|
const watermarkSharp = this.sharp(watermarkBuffer).png().modulate({ brightness: 1, saturation: 1, alpha: watermarkOptions.opacity });
|
|
@@ -1295,8 +1295,7 @@ var ImageProcessor = class {
|
|
|
1295
1295
|
createTextWatermarkSvg(text2, opacity) {
|
|
1296
1296
|
const fontSize = 24;
|
|
1297
1297
|
const padding = 10;
|
|
1298
|
-
return
|
|
1299
|
-
<svg width="200" height="50" xmlns="http://www.w3.org/2000/svg">
|
|
1298
|
+
return `<svg width="200" height="50" xmlns="http://www.w3.org/2000/svg">
|
|
1300
1299
|
<text
|
|
1301
1300
|
x="${padding}"
|
|
1302
1301
|
y="${fontSize + padding}"
|
|
@@ -1310,8 +1309,7 @@ var ImageProcessor = class {
|
|
|
1310
1309
|
>
|
|
1311
1310
|
${text2}
|
|
1312
1311
|
</text>
|
|
1313
|
-
</svg
|
|
1314
|
-
`.trim();
|
|
1312
|
+
</svg>`.trim();
|
|
1315
1313
|
}
|
|
1316
1314
|
/**
|
|
1317
1315
|
* 获取水印位置对应的gravity值
|
|
@@ -1396,7 +1394,7 @@ var ImageProcessor = class {
|
|
|
1396
1394
|
fit: "cover",
|
|
1397
1395
|
position: "center"
|
|
1398
1396
|
}).jpeg({ quality: 70 }).toFile(thumbnailPath);
|
|
1399
|
-
logger2.info(
|
|
1397
|
+
logger2.info("\u{1F5BC}\uFE0F [ImageProcessor] \u7F29\u7565\u56FE\u751F\u6210\u5B8C\u6210: " + thumbnailPath);
|
|
1400
1398
|
return thumbnailPath;
|
|
1401
1399
|
} catch (error) {
|
|
1402
1400
|
console.warn(`\u26A0\uFE0F [ImageProcessor] \u7F29\u7565\u56FE\u751F\u6210\u5931\u8D25:`, error);
|
|
@@ -1409,7 +1407,7 @@ var ImageProcessor = class {
|
|
|
1409
1407
|
getThumbnailPath(originalPath) {
|
|
1410
1408
|
const ext = path3.extname(originalPath);
|
|
1411
1409
|
const basePath = originalPath.replace(ext, "");
|
|
1412
|
-
return
|
|
1410
|
+
return basePath + "_thumb" + ext;
|
|
1413
1411
|
}
|
|
1414
1412
|
/**
|
|
1415
1413
|
* 创建模拟Sharp对象(开发测试用)
|
|
@@ -1417,7 +1415,7 @@ var ImageProcessor = class {
|
|
|
1417
1415
|
createMockSharp() {
|
|
1418
1416
|
logger2.info("\u{1F9EA} [ImageProcessor] \u521B\u5EFA\u6A21\u62DFSharp\u5904\u7406\u5668");
|
|
1419
1417
|
const mockSharp = (input) => {
|
|
1420
|
-
logger2.info(
|
|
1418
|
+
logger2.info("\u{1F9EA} [MockSharp] \u5904\u7406\u56FE\u7247: " + input);
|
|
1421
1419
|
return {
|
|
1422
1420
|
metadata: async () => ({
|
|
1423
1421
|
format: "jpeg",
|
|
@@ -1456,10 +1454,10 @@ var ImageProcessor = class {
|
|
|
1456
1454
|
return mockSharp(input);
|
|
1457
1455
|
},
|
|
1458
1456
|
toFile: async (outputPath) => {
|
|
1459
|
-
logger2.info(
|
|
1457
|
+
logger2.info("\u{1F9EA} [MockSharp] \u4FDD\u5B58\u5230\u6587\u4EF6: " + outputPath);
|
|
1460
1458
|
const outputDir = path3.dirname(outputPath);
|
|
1461
1459
|
await promises.mkdir(outputDir, { recursive: true });
|
|
1462
|
-
await promises.writeFile(outputPath,
|
|
1460
|
+
await promises.writeFile(outputPath, "Mock processed image from " + input);
|
|
1463
1461
|
return {
|
|
1464
1462
|
format: "jpeg",
|
|
1465
1463
|
width: 800,
|
|
@@ -1483,7 +1481,7 @@ var ImageProcessor = class {
|
|
|
1483
1481
|
*/
|
|
1484
1482
|
async batchProcess(inputPaths, outputDir, options, onProgress) {
|
|
1485
1483
|
this.ensureInitialized();
|
|
1486
|
-
logger2.info(
|
|
1484
|
+
logger2.info("\u{1F5BC}\uFE0F [ImageProcessor] \u5F00\u59CB\u6279\u91CF\u5904\u7406 " + inputPaths.length + " \u5F20\u56FE\u7247");
|
|
1487
1485
|
const results = [];
|
|
1488
1486
|
for (let i = 0; i < inputPaths.length; i++) {
|
|
1489
1487
|
const inputPath = inputPaths[i];
|
|
@@ -1496,15 +1494,15 @@ var ImageProcessor = class {
|
|
|
1496
1494
|
onProgress(i + 1, inputPaths.length);
|
|
1497
1495
|
}
|
|
1498
1496
|
} catch (error) {
|
|
1499
|
-
console.error(
|
|
1497
|
+
console.error("\u274C [ImageProcessor] \u6279\u91CF\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
1500
1498
|
results.push({
|
|
1501
1499
|
success: false,
|
|
1502
|
-
error:
|
|
1500
|
+
error: "\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
1503
1501
|
});
|
|
1504
1502
|
}
|
|
1505
1503
|
}
|
|
1506
1504
|
const successCount = results.filter((r) => r.success).length;
|
|
1507
|
-
logger2.info(
|
|
1505
|
+
logger2.info("\u2705 [ImageProcessor] \u6279\u91CF\u5904\u7406\u5B8C\u6210\uFF0C\u6210\u529F: " + successCount + "/" + inputPaths.length);
|
|
1508
1506
|
return results;
|
|
1509
1507
|
}
|
|
1510
1508
|
};
|
|
@@ -1545,22 +1543,22 @@ var AudioProcessor = class {
|
|
|
1545
1543
|
}
|
|
1546
1544
|
const audioOptions = options;
|
|
1547
1545
|
const startTime = Date.now();
|
|
1548
|
-
logger3.info(
|
|
1546
|
+
logger3.info("\u{1F3B5} [AudioProcessor] \u5F00\u59CB\u5904\u7406\u97F3\u9891: " + inputPath);
|
|
1549
1547
|
try {
|
|
1550
1548
|
if (!existsSync(inputPath)) {
|
|
1551
|
-
throw new Error(
|
|
1549
|
+
throw new Error("\u8F93\u5165\u6587\u4EF6\u4E0D\u5B58\u5728: " + inputPath);
|
|
1552
1550
|
}
|
|
1553
1551
|
const outputDir = path3.dirname(outputPath);
|
|
1554
1552
|
await promises.mkdir(outputDir, { recursive: true });
|
|
1555
1553
|
const metadata = await this.getAudioMetadata(inputPath);
|
|
1556
1554
|
logger3.info(
|
|
1557
|
-
|
|
1555
|
+
"\u{1F4CA} [AudioProcessor] \u97F3\u9891\u4FE1\u606F: " + this.formatDuration(metadata.duration) + ", " + metadata.bitrate + "kbps, " + metadata.sampleRate + "Hz"
|
|
1558
1556
|
);
|
|
1559
1557
|
const outputFormat = this.determineOutputFormat(outputPath, audioOptions.format);
|
|
1560
1558
|
await this.processAudio(inputPath, outputPath, audioOptions, outputFormat);
|
|
1561
1559
|
const processedStats = await promises.stat(outputPath);
|
|
1562
1560
|
const processingTime = Date.now() - startTime;
|
|
1563
|
-
logger3.info(
|
|
1561
|
+
logger3.info("\u2705 [AudioProcessor] \u97F3\u9891\u5904\u7406\u5B8C\u6210: " + outputPath + ", \u8017\u65F6: " + processingTime + "ms");
|
|
1564
1562
|
return {
|
|
1565
1563
|
success: true,
|
|
1566
1564
|
processedPath: outputPath,
|
|
@@ -1580,10 +1578,10 @@ var AudioProcessor = class {
|
|
|
1580
1578
|
}
|
|
1581
1579
|
};
|
|
1582
1580
|
} catch (error) {
|
|
1583
|
-
console.error(
|
|
1581
|
+
console.error("\u274C [AudioProcessor] \u97F3\u9891\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
1584
1582
|
return {
|
|
1585
1583
|
success: false,
|
|
1586
|
-
error:
|
|
1584
|
+
error: "\u97F3\u9891\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
|
|
1587
1585
|
processingTime: Date.now() - startTime
|
|
1588
1586
|
};
|
|
1589
1587
|
}
|
|
@@ -1631,7 +1629,7 @@ var AudioProcessor = class {
|
|
|
1631
1629
|
quality: this.getQualityDescription(metadata.bitrate, metadata.sampleRate)
|
|
1632
1630
|
};
|
|
1633
1631
|
} catch (error) {
|
|
1634
|
-
console.error(
|
|
1632
|
+
console.error("\u274C [AudioProcessor] \u83B7\u53D6\u97F3\u9891\u4FE1\u606F\u5931\u8D25: " + filePath + ":", error);
|
|
1635
1633
|
throw error;
|
|
1636
1634
|
}
|
|
1637
1635
|
}
|
|
@@ -1652,8 +1650,8 @@ var AudioProcessor = class {
|
|
|
1652
1650
|
try {
|
|
1653
1651
|
this.ffmpeg.ffprobe(filePath, (err, metadata) => {
|
|
1654
1652
|
if (err) {
|
|
1655
|
-
console.error(
|
|
1656
|
-
reject(new Error(
|
|
1653
|
+
console.error("\u274C [AudioProcessor] \u83B7\u53D6\u97F3\u9891\u5143\u6570\u636E\u5931\u8D25: " + filePath + ":", err);
|
|
1654
|
+
reject(new Error("\u65E0\u6CD5\u8BFB\u53D6\u97F3\u9891\u5143\u6570\u636E: " + err.message));
|
|
1657
1655
|
return;
|
|
1658
1656
|
}
|
|
1659
1657
|
const audioStream = metadata.streams?.find(
|
|
@@ -1690,28 +1688,28 @@ var AudioProcessor = class {
|
|
|
1690
1688
|
command = this.setAudioCodec(command, outputFormat);
|
|
1691
1689
|
if (options.bitrate) {
|
|
1692
1690
|
command = command.audioBitrate(options.bitrate);
|
|
1693
|
-
logger3.info(
|
|
1691
|
+
logger3.info("\u{1F527} [AudioProcessor] \u8BBE\u7F6E\u6BD4\u7279\u7387: " + options.bitrate + "kbps");
|
|
1694
1692
|
}
|
|
1695
1693
|
if (options.sampleRate) {
|
|
1696
1694
|
command = command.audioFrequency(options.sampleRate);
|
|
1697
|
-
logger3.info(
|
|
1695
|
+
logger3.info("\u{1F527} [AudioProcessor] \u8BBE\u7F6E\u91C7\u6837\u7387: " + options.sampleRate + "Hz");
|
|
1698
1696
|
}
|
|
1699
1697
|
if (options.channels) {
|
|
1700
1698
|
command = command.audioChannels(options.channels);
|
|
1701
|
-
logger3.info(
|
|
1699
|
+
logger3.info("\u{1F527} [AudioProcessor] \u8BBE\u7F6E\u58F0\u9053\u6570: " + options.channels);
|
|
1702
1700
|
}
|
|
1703
1701
|
command = command.format(outputFormat);
|
|
1704
1702
|
command.on("progress", (progress) => {
|
|
1705
1703
|
if (progress.percent) {
|
|
1706
|
-
logger3.info(
|
|
1704
|
+
logger3.info("\u{1F3B5} [AudioProcessor] \u5904\u7406\u8FDB\u5EA6: " + Math.round(progress.percent) + "%");
|
|
1707
1705
|
}
|
|
1708
1706
|
});
|
|
1709
1707
|
command.on("error", (err) => {
|
|
1710
1708
|
console.error(`\u274C [AudioProcessor] FFmpeg\u5904\u7406\u9519\u8BEF:`, err);
|
|
1711
|
-
reject(new Error(
|
|
1709
|
+
reject(new Error("\u97F3\u9891\u5904\u7406\u5931\u8D25: " + err.message));
|
|
1712
1710
|
});
|
|
1713
1711
|
command.on("end", () => {
|
|
1714
|
-
logger3.info(
|
|
1712
|
+
logger3.info("\u2705 [AudioProcessor] FFmpeg\u5904\u7406\u5B8C\u6210: " + outputPath);
|
|
1715
1713
|
resolve();
|
|
1716
1714
|
});
|
|
1717
1715
|
command.save(outputPath);
|
|
@@ -1760,7 +1758,7 @@ var AudioProcessor = class {
|
|
|
1760
1758
|
formatDuration(seconds) {
|
|
1761
1759
|
const minutes = Math.floor(seconds / 60);
|
|
1762
1760
|
const remainingSeconds = Math.floor(seconds % 60);
|
|
1763
|
-
return
|
|
1761
|
+
return minutes + ":" + remainingSeconds.toString().padStart(2, "0");
|
|
1764
1762
|
}
|
|
1765
1763
|
/**
|
|
1766
1764
|
* 获取声道描述
|
|
@@ -1776,7 +1774,7 @@ var AudioProcessor = class {
|
|
|
1776
1774
|
case 8:
|
|
1777
1775
|
return "7.1\u73AF\u7ED5\u58F0";
|
|
1778
1776
|
default:
|
|
1779
|
-
return
|
|
1777
|
+
return channels + "\u58F0\u9053";
|
|
1780
1778
|
}
|
|
1781
1779
|
}
|
|
1782
1780
|
/**
|
|
@@ -1799,30 +1797,30 @@ var AudioProcessor = class {
|
|
|
1799
1797
|
createMockFFmpeg() {
|
|
1800
1798
|
logger3.info("\u{1F9EA} [AudioProcessor] \u521B\u5EFA\u6A21\u62DFFFmpeg\u5904\u7406\u5668");
|
|
1801
1799
|
const mockFFmpeg = (input) => {
|
|
1802
|
-
logger3.info(
|
|
1800
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u5904\u7406\u97F3\u9891: " + input);
|
|
1803
1801
|
return {
|
|
1804
1802
|
audioBitrate: (bitrate) => {
|
|
1805
|
-
logger3.info(
|
|
1803
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u6BD4\u7279\u7387: " + bitrate + "kbps");
|
|
1806
1804
|
return mockFFmpeg(input);
|
|
1807
1805
|
},
|
|
1808
1806
|
audioFrequency: (sampleRate) => {
|
|
1809
|
-
logger3.info(
|
|
1807
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u91C7\u6837\u7387: " + sampleRate + "Hz");
|
|
1810
1808
|
return mockFFmpeg(input);
|
|
1811
1809
|
},
|
|
1812
1810
|
audioChannels: (channels) => {
|
|
1813
|
-
logger3.info(
|
|
1811
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u58F0\u9053\u6570: " + channels);
|
|
1814
1812
|
return mockFFmpeg(input);
|
|
1815
1813
|
},
|
|
1816
1814
|
audioCodec: (codec) => {
|
|
1817
|
-
logger3.info(
|
|
1815
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u7F16\u89E3\u7801\u5668: " + codec);
|
|
1818
1816
|
return mockFFmpeg(input);
|
|
1819
1817
|
},
|
|
1820
1818
|
format: (format) => {
|
|
1821
|
-
logger3.info(
|
|
1819
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u8F93\u51FA\u683C\u5F0F: " + format);
|
|
1822
1820
|
return mockFFmpeg(input);
|
|
1823
1821
|
},
|
|
1824
1822
|
on: (event, callback) => {
|
|
1825
|
-
logger3.info(
|
|
1823
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u6CE8\u518C\u4E8B\u4EF6\u76D1\u542C: " + event);
|
|
1826
1824
|
if (event === "progress") {
|
|
1827
1825
|
setTimeout(() => callback({ percent: 50 }), 100);
|
|
1828
1826
|
setTimeout(() => callback({ percent: 100 }), 200);
|
|
@@ -1832,15 +1830,15 @@ var AudioProcessor = class {
|
|
|
1832
1830
|
return mockFFmpeg(input);
|
|
1833
1831
|
},
|
|
1834
1832
|
save: async (outputPath) => {
|
|
1835
|
-
logger3.info(
|
|
1833
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u4FDD\u5B58\u97F3\u9891\u6587\u4EF6: " + outputPath);
|
|
1836
1834
|
const outputDir = path3.dirname(outputPath);
|
|
1837
1835
|
await promises.mkdir(outputDir, { recursive: true });
|
|
1838
|
-
await promises.writeFile(outputPath,
|
|
1836
|
+
await promises.writeFile(outputPath, "Mock processed audio from " + input);
|
|
1839
1837
|
}
|
|
1840
1838
|
};
|
|
1841
1839
|
};
|
|
1842
1840
|
mockFFmpeg.ffprobe = (filePath, callback) => {
|
|
1843
|
-
logger3.info(
|
|
1841
|
+
logger3.info("\u{1F9EA} [MockFFmpeg] \u83B7\u53D6\u97F3\u9891\u5143\u6570\u636E: " + filePath);
|
|
1844
1842
|
setTimeout(() => {
|
|
1845
1843
|
const mockMetadata = {
|
|
1846
1844
|
streams: [
|
|
@@ -1868,14 +1866,14 @@ var AudioProcessor = class {
|
|
|
1868
1866
|
*/
|
|
1869
1867
|
async batchProcess(inputPaths, outputDir, options, onProgress) {
|
|
1870
1868
|
this.ensureInitialized();
|
|
1871
|
-
logger3.info(
|
|
1869
|
+
logger3.info("\u{1F3B5} [AudioProcessor] \u5F00\u59CB\u6279\u91CF\u5904\u7406 " + inputPaths.length + " \u4E2A\u97F3\u9891\u6587\u4EF6");
|
|
1872
1870
|
const results = [];
|
|
1873
1871
|
for (let i = 0; i < inputPaths.length; i++) {
|
|
1874
1872
|
const inputPath = inputPaths[i];
|
|
1875
1873
|
const fileName = path3.basename(inputPath);
|
|
1876
1874
|
const nameWithoutExt = path3.parse(fileName).name;
|
|
1877
1875
|
const outputFormat = options.format || "mp3";
|
|
1878
|
-
const outputPath = path3.join(outputDir,
|
|
1876
|
+
const outputPath = path3.join(outputDir, nameWithoutExt + "." + outputFormat);
|
|
1879
1877
|
try {
|
|
1880
1878
|
const result = await this.process(inputPath, outputPath, options);
|
|
1881
1879
|
results.push(result);
|
|
@@ -1883,15 +1881,15 @@ var AudioProcessor = class {
|
|
|
1883
1881
|
onProgress(i + 1, inputPaths.length);
|
|
1884
1882
|
}
|
|
1885
1883
|
} catch (error) {
|
|
1886
|
-
console.error(
|
|
1884
|
+
console.error("\u274C [AudioProcessor] \u6279\u91CF\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
1887
1885
|
results.push({
|
|
1888
1886
|
success: false,
|
|
1889
|
-
error:
|
|
1887
|
+
error: "\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
1890
1888
|
});
|
|
1891
1889
|
}
|
|
1892
1890
|
}
|
|
1893
1891
|
const successCount = results.filter((r) => r.success).length;
|
|
1894
|
-
logger3.info(
|
|
1892
|
+
logger3.info("\u2705 [AudioProcessor] \u6279\u91CF\u5904\u7406\u5B8C\u6210\uFF0C\u6210\u529F: " + successCount + "/" + inputPaths.length);
|
|
1895
1893
|
return results;
|
|
1896
1894
|
}
|
|
1897
1895
|
/**
|
|
@@ -1902,10 +1900,10 @@ var AudioProcessor = class {
|
|
|
1902
1900
|
return new Promise((resolve) => {
|
|
1903
1901
|
try {
|
|
1904
1902
|
this.ffmpeg(inputPath).outputOptions(["-an", "-vcodec copy"]).on("error", (err) => {
|
|
1905
|
-
console.warn(
|
|
1903
|
+
console.warn("\u26A0\uFE0F [AudioProcessor] \u63D0\u53D6\u5C01\u9762\u5931\u8D25: " + err.message);
|
|
1906
1904
|
resolve(false);
|
|
1907
1905
|
}).on("end", () => {
|
|
1908
|
-
logger3.info(
|
|
1906
|
+
logger3.info("\u{1F5BC}\uFE0F [AudioProcessor] \u97F3\u9891\u5C01\u9762\u63D0\u53D6\u5B8C\u6210: " + outputPath);
|
|
1909
1907
|
resolve(true);
|
|
1910
1908
|
}).save(outputPath);
|
|
1911
1909
|
} catch (error) {
|
|
@@ -1920,13 +1918,13 @@ var AudioProcessor = class {
|
|
|
1920
1918
|
async denoise(inputPath, outputPath) {
|
|
1921
1919
|
this.ensureInitialized();
|
|
1922
1920
|
const startTime = Date.now();
|
|
1923
|
-
logger3.info(
|
|
1921
|
+
logger3.info("\u{1F507} [AudioProcessor] \u5F00\u59CB\u97F3\u9891\u964D\u566A: " + inputPath);
|
|
1924
1922
|
return new Promise((resolve) => {
|
|
1925
1923
|
try {
|
|
1926
1924
|
this.ffmpeg(inputPath).audioFilters("highpass=f=200,lowpass=f=3000").on("error", (err) => {
|
|
1927
1925
|
resolve({
|
|
1928
1926
|
success: false,
|
|
1929
|
-
error:
|
|
1927
|
+
error: "\u964D\u566A\u5904\u7406\u5931\u8D25: " + err.message,
|
|
1930
1928
|
processingTime: Date.now() - startTime
|
|
1931
1929
|
});
|
|
1932
1930
|
}).on("end", async () => {
|
|
@@ -1945,7 +1943,7 @@ var AudioProcessor = class {
|
|
|
1945
1943
|
} catch (error) {
|
|
1946
1944
|
resolve({
|
|
1947
1945
|
success: false,
|
|
1948
|
-
error:
|
|
1946
|
+
error: "\u964D\u566A\u5904\u7406\u5F02\u5E38: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
|
|
1949
1947
|
processingTime: Date.now() - startTime
|
|
1950
1948
|
});
|
|
1951
1949
|
}
|
|
@@ -1989,16 +1987,16 @@ var VideoProcessor = class {
|
|
|
1989
1987
|
}
|
|
1990
1988
|
const videoOptions = options;
|
|
1991
1989
|
const startTime = Date.now();
|
|
1992
|
-
logger4.info(
|
|
1990
|
+
logger4.info("\u{1F3AC} [VideoProcessor] \u5F00\u59CB\u5904\u7406\u89C6\u9891: " + inputPath);
|
|
1993
1991
|
try {
|
|
1994
1992
|
if (!existsSync(inputPath)) {
|
|
1995
|
-
throw new Error(
|
|
1993
|
+
throw new Error("\u8F93\u5165\u6587\u4EF6\u4E0D\u5B58\u5728: " + inputPath);
|
|
1996
1994
|
}
|
|
1997
1995
|
const outputDir = path3.dirname(outputPath);
|
|
1998
1996
|
await promises.mkdir(outputDir, { recursive: true });
|
|
1999
1997
|
const metadata = await this.getVideoMetadata(inputPath);
|
|
2000
1998
|
logger4.info(
|
|
2001
|
-
|
|
1999
|
+
"\u{1F4CA} [VideoProcessor] \u89C6\u9891\u4FE1\u606F: " + metadata.width + "x" + metadata.height + ", " + this.formatDuration(metadata.duration) + ", " + metadata.fps + "fps"
|
|
2002
2000
|
);
|
|
2003
2001
|
const outputFormat = this.determineOutputFormat(outputPath, videoOptions.format);
|
|
2004
2002
|
await this.processVideo(inputPath, outputPath, videoOptions, outputFormat);
|
|
@@ -2012,7 +2010,7 @@ var VideoProcessor = class {
|
|
|
2012
2010
|
}
|
|
2013
2011
|
const processedStats = await promises.stat(outputPath);
|
|
2014
2012
|
const processingTime = Date.now() - startTime;
|
|
2015
|
-
logger4.info(
|
|
2013
|
+
logger4.info("\u2705 [VideoProcessor] \u89C6\u9891\u5904\u7406\u5B8C\u6210: " + outputPath + ", \u8017\u65F6: " + processingTime + "ms");
|
|
2016
2014
|
return {
|
|
2017
2015
|
success: true,
|
|
2018
2016
|
processedPath: outputPath,
|
|
@@ -2036,10 +2034,10 @@ var VideoProcessor = class {
|
|
|
2036
2034
|
}
|
|
2037
2035
|
};
|
|
2038
2036
|
} catch (error) {
|
|
2039
|
-
console.error(
|
|
2037
|
+
console.error("\u274C [VideoProcessor] \u89C6\u9891\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
2040
2038
|
return {
|
|
2041
2039
|
success: false,
|
|
2042
|
-
error:
|
|
2040
|
+
error: "\u89C6\u9891\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"),
|
|
2043
2041
|
processingTime: Date.now() - startTime
|
|
2044
2042
|
};
|
|
2045
2043
|
}
|
|
@@ -2091,7 +2089,7 @@ var VideoProcessor = class {
|
|
|
2091
2089
|
quality: this.getQualityDescription(metadata.width, metadata.height, metadata.bitrate)
|
|
2092
2090
|
};
|
|
2093
2091
|
} catch (error) {
|
|
2094
|
-
console.error(
|
|
2092
|
+
console.error("\u274C [VideoProcessor] \u83B7\u53D6\u89C6\u9891\u4FE1\u606F\u5931\u8D25: " + filePath + ":", error);
|
|
2095
2093
|
throw error;
|
|
2096
2094
|
}
|
|
2097
2095
|
}
|
|
@@ -2112,8 +2110,8 @@ var VideoProcessor = class {
|
|
|
2112
2110
|
try {
|
|
2113
2111
|
this.ffmpeg.ffprobe(filePath, (err, metadata) => {
|
|
2114
2112
|
if (err) {
|
|
2115
|
-
console.error(
|
|
2116
|
-
reject(new Error(
|
|
2113
|
+
console.error("\u274C [VideoProcessor] \u83B7\u53D6\u89C6\u9891\u5143\u6570\u636E\u5931\u8D25: " + filePath + ":", err);
|
|
2114
|
+
reject(new Error("\u65E0\u6CD5\u8BFB\u53D6\u89C6\u9891\u5143\u6570\u636E: " + err.message));
|
|
2117
2115
|
return;
|
|
2118
2116
|
}
|
|
2119
2117
|
const videoStream = metadata.streams?.find(
|
|
@@ -2163,20 +2161,20 @@ var VideoProcessor = class {
|
|
|
2163
2161
|
command = this.setVideoCodec(command, outputFormat);
|
|
2164
2162
|
if (options.quality) {
|
|
2165
2163
|
command = this.setVideoQuality(command, options.quality);
|
|
2166
|
-
logger4.info(
|
|
2164
|
+
logger4.info("\u{1F527} [VideoProcessor] \u8BBE\u7F6E\u89C6\u9891\u8D28\u91CF: " + options.quality);
|
|
2167
2165
|
}
|
|
2168
2166
|
command = command.format(outputFormat);
|
|
2169
2167
|
command.on("progress", (progress) => {
|
|
2170
2168
|
if (progress.percent) {
|
|
2171
|
-
logger4.info(
|
|
2169
|
+
logger4.info("\u{1F3AC} [VideoProcessor] \u5904\u7406\u8FDB\u5EA6: " + Math.round(progress.percent) + "%");
|
|
2172
2170
|
}
|
|
2173
2171
|
});
|
|
2174
2172
|
command.on("error", (err) => {
|
|
2175
2173
|
console.error(`\u274C [VideoProcessor] FFmpeg\u5904\u7406\u9519\u8BEF:`, err);
|
|
2176
|
-
reject(new Error(
|
|
2174
|
+
reject(new Error("\u89C6\u9891\u5904\u7406\u5931\u8D25: " + err.message));
|
|
2177
2175
|
});
|
|
2178
2176
|
command.on("end", () => {
|
|
2179
|
-
logger4.info(
|
|
2177
|
+
logger4.info("\u2705 [VideoProcessor] FFmpeg\u5904\u7406\u5B8C\u6210: " + outputPath);
|
|
2180
2178
|
resolve();
|
|
2181
2179
|
});
|
|
2182
2180
|
command.save(outputPath);
|
|
@@ -2207,7 +2205,7 @@ var VideoProcessor = class {
|
|
|
2207
2205
|
*/
|
|
2208
2206
|
setVideoQuality(command, quality) {
|
|
2209
2207
|
const crf = Math.max(18, Math.min(51, 51 - Math.floor(quality * 0.33)));
|
|
2210
|
-
return command.outputOptions([
|
|
2208
|
+
return command.outputOptions(["-crf " + crf]);
|
|
2211
2209
|
}
|
|
2212
2210
|
/**
|
|
2213
2211
|
* 确定输出格式
|
|
@@ -2233,10 +2231,10 @@ var VideoProcessor = class {
|
|
|
2233
2231
|
try {
|
|
2234
2232
|
const thumbnailPath = this.getThumbnailPath(outputPath);
|
|
2235
2233
|
this.ffmpeg(inputPath).seekInput(timeOffset).frames(1).size("320x240").on("error", (err) => {
|
|
2236
|
-
console.warn(
|
|
2234
|
+
console.warn("\u26A0\uFE0F [VideoProcessor] \u7F29\u7565\u56FE\u751F\u6210\u5931\u8D25: " + err.message);
|
|
2237
2235
|
reject(err);
|
|
2238
2236
|
}).on("end", () => {
|
|
2239
|
-
logger4.info(
|
|
2237
|
+
logger4.info("\u{1F5BC}\uFE0F [VideoProcessor] \u89C6\u9891\u7F29\u7565\u56FE\u751F\u6210\u5B8C\u6210: " + thumbnailPath);
|
|
2240
2238
|
resolve(thumbnailPath);
|
|
2241
2239
|
}).save(thumbnailPath);
|
|
2242
2240
|
} catch (error) {
|
|
@@ -2251,7 +2249,7 @@ var VideoProcessor = class {
|
|
|
2251
2249
|
getThumbnailPath(originalPath) {
|
|
2252
2250
|
const ext = path3.extname(originalPath);
|
|
2253
2251
|
const basePath = originalPath.replace(ext, "");
|
|
2254
|
-
return
|
|
2252
|
+
return basePath + "_thumb.jpg";
|
|
2255
2253
|
}
|
|
2256
2254
|
/**
|
|
2257
2255
|
* 格式化时长显示
|
|
@@ -2261,9 +2259,9 @@ var VideoProcessor = class {
|
|
|
2261
2259
|
const minutes = Math.floor(seconds % 3600 / 60);
|
|
2262
2260
|
const remainingSeconds = Math.floor(seconds % 60);
|
|
2263
2261
|
if (hours > 0) {
|
|
2264
|
-
return
|
|
2262
|
+
return hours + ":" + minutes.toString().padStart(2, "0") + ":" + remainingSeconds.toString().padStart(2, "0");
|
|
2265
2263
|
} else {
|
|
2266
|
-
return
|
|
2264
|
+
return minutes + ":" + remainingSeconds.toString().padStart(2, "0");
|
|
2267
2265
|
}
|
|
2268
2266
|
}
|
|
2269
2267
|
/**
|
|
@@ -2279,7 +2277,7 @@ var VideoProcessor = class {
|
|
|
2279
2277
|
} else if (width >= 640 && height >= 480) {
|
|
2280
2278
|
return "480p SD";
|
|
2281
2279
|
} else {
|
|
2282
|
-
return
|
|
2280
|
+
return width + "x" + height;
|
|
2283
2281
|
}
|
|
2284
2282
|
}
|
|
2285
2283
|
/**
|
|
@@ -2304,18 +2302,18 @@ var VideoProcessor = class {
|
|
|
2304
2302
|
createMockFFmpeg() {
|
|
2305
2303
|
logger4.info("\u{1F9EA} [VideoProcessor] \u521B\u5EFA\u6A21\u62DFFFmpeg\u5904\u7406\u5668");
|
|
2306
2304
|
const mockFFmpeg = (input) => {
|
|
2307
|
-
logger4.info(
|
|
2305
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u5904\u7406\u89C6\u9891: " + input);
|
|
2308
2306
|
return {
|
|
2309
2307
|
videoCodec: (codec) => {
|
|
2310
|
-
logger4.info(
|
|
2308
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u89C6\u9891\u7F16\u89E3\u7801\u5668: " + codec);
|
|
2311
2309
|
return mockFFmpeg(input);
|
|
2312
2310
|
},
|
|
2313
2311
|
audioCodec: (codec) => {
|
|
2314
|
-
logger4.info(
|
|
2312
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u97F3\u9891\u7F16\u89E3\u7801\u5668: " + codec);
|
|
2315
2313
|
return mockFFmpeg(input);
|
|
2316
2314
|
},
|
|
2317
2315
|
format: (format) => {
|
|
2318
|
-
logger4.info(
|
|
2316
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u8F93\u51FA\u683C\u5F0F: " + format);
|
|
2319
2317
|
return mockFFmpeg(input);
|
|
2320
2318
|
},
|
|
2321
2319
|
outputOptions: (options) => {
|
|
@@ -2323,19 +2321,19 @@ var VideoProcessor = class {
|
|
|
2323
2321
|
return mockFFmpeg(input);
|
|
2324
2322
|
},
|
|
2325
2323
|
seekInput: (time) => {
|
|
2326
|
-
logger4.info(
|
|
2324
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u8DF3\u8F6C\u5230\u65F6\u95F4: " + time + "s");
|
|
2327
2325
|
return mockFFmpeg(input);
|
|
2328
2326
|
},
|
|
2329
2327
|
frames: (count) => {
|
|
2330
|
-
logger4.info(
|
|
2328
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u63D0\u53D6\u5E27\u6570: " + count);
|
|
2331
2329
|
return mockFFmpeg(input);
|
|
2332
2330
|
},
|
|
2333
2331
|
size: (size) => {
|
|
2334
|
-
logger4.info(
|
|
2332
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u8BBE\u7F6E\u5C3A\u5BF8: " + size);
|
|
2335
2333
|
return mockFFmpeg(input);
|
|
2336
2334
|
},
|
|
2337
2335
|
on: (event, callback) => {
|
|
2338
|
-
logger4.info(
|
|
2336
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u6CE8\u518C\u4E8B\u4EF6\u76D1\u542C: " + event);
|
|
2339
2337
|
if (event === "progress") {
|
|
2340
2338
|
setTimeout(() => callback({ percent: 25 }), 100);
|
|
2341
2339
|
setTimeout(() => callback({ percent: 50 }), 200);
|
|
@@ -2347,15 +2345,15 @@ var VideoProcessor = class {
|
|
|
2347
2345
|
return mockFFmpeg(input);
|
|
2348
2346
|
},
|
|
2349
2347
|
save: async (outputPath) => {
|
|
2350
|
-
logger4.info(
|
|
2348
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u4FDD\u5B58\u89C6\u9891\u6587\u4EF6: " + outputPath);
|
|
2351
2349
|
const outputDir = path3.dirname(outputPath);
|
|
2352
2350
|
await promises.mkdir(outputDir, { recursive: true });
|
|
2353
|
-
await promises.writeFile(outputPath,
|
|
2351
|
+
await promises.writeFile(outputPath, "Mock processed video from " + input);
|
|
2354
2352
|
}
|
|
2355
2353
|
};
|
|
2356
2354
|
};
|
|
2357
2355
|
mockFFmpeg.ffprobe = (filePath, callback) => {
|
|
2358
|
-
logger4.info(
|
|
2356
|
+
logger4.info("\u{1F9EA} [MockFFmpeg] \u83B7\u53D6\u89C6\u9891\u5143\u6570\u636E: " + filePath);
|
|
2359
2357
|
setTimeout(() => {
|
|
2360
2358
|
const mockMetadata = {
|
|
2361
2359
|
streams: [
|
|
@@ -2384,14 +2382,14 @@ var VideoProcessor = class {
|
|
|
2384
2382
|
*/
|
|
2385
2383
|
async batchProcess(inputPaths, outputDir, options, onProgress) {
|
|
2386
2384
|
this.ensureInitialized();
|
|
2387
|
-
logger4.info(
|
|
2385
|
+
logger4.info("\u{1F3AC} [VideoProcessor] \u5F00\u59CB\u6279\u91CF\u5904\u7406 " + inputPaths.length + " \u4E2A\u89C6\u9891\u6587\u4EF6");
|
|
2388
2386
|
const results = [];
|
|
2389
2387
|
for (let i = 0; i < inputPaths.length; i++) {
|
|
2390
2388
|
const inputPath = inputPaths[i];
|
|
2391
2389
|
const fileName = path3.basename(inputPath);
|
|
2392
2390
|
const nameWithoutExt = path3.parse(fileName).name;
|
|
2393
2391
|
const outputFormat = options.format || "mp4";
|
|
2394
|
-
const outputPath = path3.join(outputDir,
|
|
2392
|
+
const outputPath = path3.join(outputDir, nameWithoutExt + "." + outputFormat);
|
|
2395
2393
|
try {
|
|
2396
2394
|
const result = await this.process(inputPath, outputPath, options);
|
|
2397
2395
|
results.push(result);
|
|
@@ -2399,15 +2397,15 @@ var VideoProcessor = class {
|
|
|
2399
2397
|
onProgress(i + 1, inputPaths.length);
|
|
2400
2398
|
}
|
|
2401
2399
|
} catch (error) {
|
|
2402
|
-
console.error(
|
|
2400
|
+
console.error("\u274C [VideoProcessor] \u6279\u91CF\u5904\u7406\u5931\u8D25: " + inputPath + ":", error);
|
|
2403
2401
|
results.push({
|
|
2404
2402
|
success: false,
|
|
2405
|
-
error:
|
|
2403
|
+
error: "\u5904\u7406\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
2406
2404
|
});
|
|
2407
2405
|
}
|
|
2408
2406
|
}
|
|
2409
2407
|
const successCount = results.filter((r) => r.success).length;
|
|
2410
|
-
logger4.info(
|
|
2408
|
+
logger4.info("\u2705 [VideoProcessor] \u6279\u91CF\u5904\u7406\u5B8C\u6210\uFF0C\u6210\u529F: " + successCount + "/" + inputPaths.length);
|
|
2411
2409
|
return results;
|
|
2412
2410
|
}
|
|
2413
2411
|
/**
|
|
@@ -2416,24 +2414,24 @@ var VideoProcessor = class {
|
|
|
2416
2414
|
async extractFrames(inputPath, outputDir, options = {}) {
|
|
2417
2415
|
this.ensureInitialized();
|
|
2418
2416
|
const { count = 10, interval, format = "jpg" } = options;
|
|
2419
|
-
logger4.info(
|
|
2417
|
+
logger4.info("\u{1F5BC}\uFE0F [VideoProcessor] \u63D0\u53D6\u89C6\u9891\u5E27: " + inputPath + ", \u6570\u91CF: " + count);
|
|
2420
2418
|
return new Promise((resolve, reject) => {
|
|
2421
2419
|
try {
|
|
2422
2420
|
let command = this.ffmpeg(inputPath);
|
|
2423
2421
|
if (interval) {
|
|
2424
|
-
command = command.outputOptions([
|
|
2422
|
+
command = command.outputOptions(["-vf fps=1/" + interval]);
|
|
2425
2423
|
} else {
|
|
2426
2424
|
command = command.frames(count);
|
|
2427
2425
|
}
|
|
2428
|
-
const outputPattern = path3.join(outputDir,
|
|
2426
|
+
const outputPattern = path3.join(outputDir, "frame_%03d." + format);
|
|
2429
2427
|
command.on("error", (err) => {
|
|
2430
2428
|
console.error(`\u274C [VideoProcessor] \u63D0\u53D6\u5E27\u5931\u8D25:`, err);
|
|
2431
|
-
reject(new Error(
|
|
2429
|
+
reject(new Error("\u63D0\u53D6\u5E27\u5931\u8D25: " + err.message));
|
|
2432
2430
|
}).on("end", async () => {
|
|
2433
2431
|
try {
|
|
2434
2432
|
const files = await promises.readdir(outputDir);
|
|
2435
|
-
const frameFiles = files.filter((file) => file.startsWith("frame_") && file.endsWith(
|
|
2436
|
-
logger4.info(
|
|
2433
|
+
const frameFiles = files.filter((file) => file.startsWith("frame_") && file.endsWith("." + format)).sort().map((file) => path3.join(outputDir, file));
|
|
2434
|
+
logger4.info("\u2705 [VideoProcessor] \u5E27\u63D0\u53D6\u5B8C\u6210\uFF0C\u5171 " + frameFiles.length + " \u5E27");
|
|
2437
2435
|
resolve(frameFiles);
|
|
2438
2436
|
} catch (error) {
|
|
2439
2437
|
reject(error);
|
|
@@ -2449,7 +2447,7 @@ var VideoProcessor = class {
|
|
|
2449
2447
|
*/
|
|
2450
2448
|
async compress(inputPath, outputPath, compressionLevel = "medium") {
|
|
2451
2449
|
this.ensureInitialized();
|
|
2452
|
-
logger4.info(
|
|
2450
|
+
logger4.info("\u{1F5DC}\uFE0F [VideoProcessor] \u5F00\u59CB\u89C6\u9891\u538B\u7F29: " + inputPath + ", \u7EA7\u522B: " + compressionLevel);
|
|
2453
2451
|
const options = {
|
|
2454
2452
|
type: "video",
|
|
2455
2453
|
quality: this.getCompressionQuality(compressionLevel),
|
|
@@ -2500,7 +2498,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2500
2498
|
*/
|
|
2501
2499
|
registerProcessor(processor) {
|
|
2502
2500
|
this.processors.set(processor.type, processor);
|
|
2503
|
-
logger5.info(
|
|
2501
|
+
logger5.info("\u{1F527} [ProcessingQueue] \u6CE8\u518C\u5904\u7406\u5668: " + processor.type);
|
|
2504
2502
|
}
|
|
2505
2503
|
/**
|
|
2506
2504
|
* 添加任务到队列
|
|
@@ -2522,11 +2520,11 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2522
2520
|
};
|
|
2523
2521
|
const processor = this.processors.get(options.type);
|
|
2524
2522
|
if (!processor) {
|
|
2525
|
-
throw new Error(
|
|
2523
|
+
throw new Error("\u672A\u627E\u5230\u7C7B\u578B\u4E3A " + options.type + " \u7684\u6587\u4EF6\u5904\u7406\u5668");
|
|
2526
2524
|
}
|
|
2527
2525
|
task.processor = processor;
|
|
2528
2526
|
this.tasks.set(taskId, task);
|
|
2529
|
-
logger5.info(
|
|
2527
|
+
logger5.info("\u{1F4DD} [ProcessingQueue] \u6DFB\u52A0\u4EFB\u52A1: " + taskId + " (" + inputPath + ")");
|
|
2530
2528
|
this.emit("taskAdded", task);
|
|
2531
2529
|
if (this.isStarted) {
|
|
2532
2530
|
this.processNext();
|
|
@@ -2571,15 +2569,15 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2571
2569
|
pauseTask(taskId) {
|
|
2572
2570
|
const task = this.tasks.get(taskId);
|
|
2573
2571
|
if (!task) {
|
|
2574
|
-
console.warn(
|
|
2572
|
+
console.warn("\u26A0\uFE0F [ProcessingQueue] \u4EFB\u52A1\u4E0D\u5B58\u5728: " + taskId);
|
|
2575
2573
|
return false;
|
|
2576
2574
|
}
|
|
2577
2575
|
if (task.status === "running") {
|
|
2578
|
-
console.warn(
|
|
2576
|
+
console.warn("\u26A0\uFE0F [ProcessingQueue] \u65E0\u6CD5\u6682\u505C\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1: " + taskId);
|
|
2579
2577
|
return false;
|
|
2580
2578
|
}
|
|
2581
2579
|
task.status = "cancelled";
|
|
2582
|
-
logger5.info(
|
|
2580
|
+
logger5.info("\u23F8\uFE0F [ProcessingQueue] \u6682\u505C\u4EFB\u52A1: " + taskId);
|
|
2583
2581
|
this.emit("taskCancelled", task);
|
|
2584
2582
|
return true;
|
|
2585
2583
|
}
|
|
@@ -2589,15 +2587,15 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2589
2587
|
cancelTask(taskId) {
|
|
2590
2588
|
const task = this.tasks.get(taskId);
|
|
2591
2589
|
if (!task) {
|
|
2592
|
-
console.warn(
|
|
2590
|
+
console.warn("\u26A0\uFE0F [ProcessingQueue] \u4EFB\u52A1\u4E0D\u5B58\u5728: " + taskId);
|
|
2593
2591
|
return false;
|
|
2594
2592
|
}
|
|
2595
2593
|
if (task.status === "running") {
|
|
2596
|
-
console.warn(
|
|
2594
|
+
console.warn("\u26A0\uFE0F [ProcessingQueue] \u65E0\u6CD5\u53D6\u6D88\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1: " + taskId);
|
|
2597
2595
|
return false;
|
|
2598
2596
|
}
|
|
2599
2597
|
task.status = "cancelled";
|
|
2600
|
-
logger5.info(
|
|
2598
|
+
logger5.info("\u274C [ProcessingQueue] \u53D6\u6D88\u4EFB\u52A1: " + taskId);
|
|
2601
2599
|
this.emit("taskCancelled", task);
|
|
2602
2600
|
return true;
|
|
2603
2601
|
}
|
|
@@ -2660,7 +2658,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2660
2658
|
}
|
|
2661
2659
|
const afterCount = this.tasks.size;
|
|
2662
2660
|
const cleanedCount = beforeCount - afterCount;
|
|
2663
|
-
logger5.info(
|
|
2661
|
+
logger5.info("\u{1F9F9} [ProcessingQueue] \u6E05\u7406\u5B8C\u6210\uFF0C\u79FB\u9664 " + cleanedCount + " \u4E2A\u4EFB\u52A1");
|
|
2664
2662
|
this.emit("cleanup", { cleaned: cleanedCount, remaining: afterCount });
|
|
2665
2663
|
}
|
|
2666
2664
|
// ============= 私有方法 =============
|
|
@@ -2711,7 +2709,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2711
2709
|
this.failTask(task, "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u6587\u4EF6\u5904\u7406\u5668");
|
|
2712
2710
|
return;
|
|
2713
2711
|
}
|
|
2714
|
-
logger5.info(
|
|
2712
|
+
logger5.info("\u{1F680} [ProcessingQueue] \u5F00\u59CB\u5904\u7406\u4EFB\u52A1: " + task.id);
|
|
2715
2713
|
task.status = "running";
|
|
2716
2714
|
task.startTime = Date.now();
|
|
2717
2715
|
this.runningTasks.add(task.id);
|
|
@@ -2743,7 +2741,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2743
2741
|
task.endTime = Date.now();
|
|
2744
2742
|
task.result = result;
|
|
2745
2743
|
this.runningTasks.delete(task.id);
|
|
2746
|
-
logger5.info(
|
|
2744
|
+
logger5.info("\u2705 [ProcessingQueue] \u4EFB\u52A1\u5B8C\u6210: " + task.id);
|
|
2747
2745
|
if (task.onComplete) {
|
|
2748
2746
|
try {
|
|
2749
2747
|
task.onComplete(task, result);
|
|
@@ -2763,7 +2761,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2763
2761
|
task.retries++;
|
|
2764
2762
|
task.status = "pending";
|
|
2765
2763
|
task.error = void 0;
|
|
2766
|
-
logger5.info(
|
|
2764
|
+
logger5.info("\u{1F504} [ProcessingQueue] \u91CD\u8BD5\u4EFB\u52A1: " + task.id + " (" + task.retries + "/" + task.maxRetries + ")");
|
|
2767
2765
|
this.emit("taskRetried", task);
|
|
2768
2766
|
setTimeout(() => {
|
|
2769
2767
|
if (this.isStarted) {
|
|
@@ -2782,7 +2780,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2782
2780
|
task.endTime = Date.now();
|
|
2783
2781
|
task.error = error;
|
|
2784
2782
|
this.runningTasks.delete(task.id);
|
|
2785
|
-
console.error(
|
|
2783
|
+
console.error("\u274C [ProcessingQueue] \u4EFB\u52A1\u5931\u8D25: " + task.id + " - " + error);
|
|
2786
2784
|
if (task.onError) {
|
|
2787
2785
|
try {
|
|
2788
2786
|
task.onError(task, error);
|
|
@@ -2797,7 +2795,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2797
2795
|
* 生成唯一任务ID
|
|
2798
2796
|
*/
|
|
2799
2797
|
generateTaskId() {
|
|
2800
|
-
return
|
|
2798
|
+
return "task_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
|
|
2801
2799
|
}
|
|
2802
2800
|
/**
|
|
2803
2801
|
* 批量添加任务
|
|
@@ -2806,7 +2804,7 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2806
2804
|
const taskIds = [];
|
|
2807
2805
|
const results = /* @__PURE__ */ new Map();
|
|
2808
2806
|
let completedCount = 0;
|
|
2809
|
-
logger5.info(
|
|
2807
|
+
logger5.info("\u{1F4E6} [ProcessingQueue] \u6279\u91CF\u6DFB\u52A0 " + tasks.length + " \u4E2A\u4EFB\u52A1");
|
|
2810
2808
|
for (const taskSpec of tasks) {
|
|
2811
2809
|
const taskId = this.addTask(taskSpec.inputPath, taskSpec.outputPath, taskSpec.options, {
|
|
2812
2810
|
priority: taskSpec.priority,
|
|
@@ -2843,15 +2841,15 @@ var ProcessingQueue = class extends EventEmitter {
|
|
|
2843
2841
|
const issues = [];
|
|
2844
2842
|
const recommendations = [];
|
|
2845
2843
|
if (stats.successRate < 0.8 && stats.totalTasks > 10) {
|
|
2846
|
-
issues.push(
|
|
2844
|
+
issues.push("\u6210\u529F\u7387\u8FC7\u4F4E: " + (stats.successRate * 100).toFixed(1) + "%");
|
|
2847
2845
|
recommendations.push("\u68C0\u67E5\u6587\u4EF6\u5904\u7406\u5668\u914D\u7F6E\u548C\u8F93\u5165\u6587\u4EF6\u8D28\u91CF");
|
|
2848
2846
|
}
|
|
2849
2847
|
if (stats.pendingTasks > 50) {
|
|
2850
|
-
issues.push(
|
|
2848
|
+
issues.push("\u5F85\u5904\u7406\u4EFB\u52A1\u79EF\u538B: " + stats.pendingTasks + " \u4E2A");
|
|
2851
2849
|
recommendations.push("\u8003\u8651\u589E\u52A0\u5E76\u53D1\u5904\u7406\u6570\u6216\u4F18\u5316\u5904\u7406\u6027\u80FD");
|
|
2852
2850
|
}
|
|
2853
2851
|
if (stats.averageProcessingTime > 6e4) {
|
|
2854
|
-
issues.push(
|
|
2852
|
+
issues.push("\u5E73\u5747\u5904\u7406\u65F6\u95F4\u8FC7\u957F: " + (stats.averageProcessingTime / 1e3).toFixed(1) + "\u79D2");
|
|
2855
2853
|
recommendations.push("\u4F18\u5316\u6587\u4EF6\u5904\u7406\u903B\u8F91\u6216\u51CF\u5C11\u5904\u7406\u590D\u6742\u5EA6");
|
|
2856
2854
|
}
|
|
2857
2855
|
return {
|
|
@@ -2951,23 +2949,23 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
2951
2949
|
try {
|
|
2952
2950
|
const metadata = data.metadata || data;
|
|
2953
2951
|
await repository.save(metadata);
|
|
2954
|
-
logger6.info(
|
|
2952
|
+
logger6.info("\u{1F4BE} [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u4FDD\u5B58: " + fileId);
|
|
2955
2953
|
} catch (error) {
|
|
2956
|
-
logger6.error(
|
|
2954
|
+
logger6.error("\u274C [Persistence] \u4FDD\u5B58\u5931\u8D25: " + fileId, error);
|
|
2957
2955
|
}
|
|
2958
2956
|
});
|
|
2959
2957
|
this.on("file:deleted", async (fileId) => {
|
|
2960
2958
|
try {
|
|
2961
2959
|
await repository.delete(fileId);
|
|
2962
|
-
logger6.info(
|
|
2960
|
+
logger6.info("\u{1F5D1}\uFE0F [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u5220\u9664: " + fileId);
|
|
2963
2961
|
} catch (error) {
|
|
2964
|
-
logger6.error(
|
|
2962
|
+
logger6.error("\u274C [Persistence] \u5220\u9664\u5931\u8D25: " + fileId, error);
|
|
2965
2963
|
}
|
|
2966
2964
|
});
|
|
2967
2965
|
this.on("files:batch-deleted", async (fileIds) => {
|
|
2968
2966
|
try {
|
|
2969
2967
|
await repository.batchDelete(fileIds);
|
|
2970
|
-
logger6.info(
|
|
2968
|
+
logger6.info("\u{1F5D1}\uFE0F [Persistence] \u6279\u91CF\u5220\u9664\u5143\u6570\u636E: " + fileIds.length + " \u4E2A\u6587\u4EF6");
|
|
2971
2969
|
} catch (error) {
|
|
2972
2970
|
logger6.error(`\u274C [Persistence] \u6279\u91CF\u5220\u9664\u5931\u8D25`, error);
|
|
2973
2971
|
}
|
|
@@ -2999,16 +2997,16 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
2999
2997
|
for (const [type, provider] of this.storageProviders) {
|
|
3000
2998
|
if ("reinitialize" in provider) {
|
|
3001
2999
|
try {
|
|
3002
|
-
logger6.info(
|
|
3000
|
+
logger6.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005: " + type + "...");
|
|
3003
3001
|
const config = this.config.storageProviders?.[type];
|
|
3004
3002
|
if (config) {
|
|
3005
3003
|
await provider.reinitialize(config);
|
|
3006
|
-
logger6.info(
|
|
3004
|
+
logger6.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210: " + type);
|
|
3007
3005
|
} else {
|
|
3008
|
-
logger6.warn(
|
|
3006
|
+
logger6.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u914D\u7F6E\u4E0D\u5B58\u5728: " + type);
|
|
3009
3007
|
}
|
|
3010
3008
|
} catch (error) {
|
|
3011
|
-
logger6.error(
|
|
3009
|
+
logger6.error("\u274C [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25: " + type, error);
|
|
3012
3010
|
}
|
|
3013
3011
|
}
|
|
3014
3012
|
}
|
|
@@ -3023,21 +3021,21 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3023
3021
|
*/
|
|
3024
3022
|
registerStorageProvider(provider) {
|
|
3025
3023
|
this.storageProviders.set(provider.type, provider);
|
|
3026
|
-
logger6.info(
|
|
3024
|
+
logger6.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u5B58\u50A8\u63D0\u4F9B\u8005: " + provider.type);
|
|
3027
3025
|
}
|
|
3028
3026
|
/**
|
|
3029
3027
|
* 注册CDN提供者
|
|
3030
3028
|
*/
|
|
3031
3029
|
registerCDNProvider(provider) {
|
|
3032
3030
|
this.cdnProviders.set(provider.type, provider);
|
|
3033
|
-
logger6.info(
|
|
3031
|
+
logger6.info("\u{1F310} [UniversalFileService] \u6CE8\u518CCDN\u63D0\u4F9B\u8005: " + provider.type);
|
|
3034
3032
|
}
|
|
3035
3033
|
/**
|
|
3036
3034
|
* 注册文件处理器
|
|
3037
3035
|
*/
|
|
3038
3036
|
registerFileProcessor(processor) {
|
|
3039
3037
|
this.fileProcessors.set(processor.type, processor);
|
|
3040
|
-
logger6.info(
|
|
3038
|
+
logger6.info("\u2699\uFE0F [UniversalFileService] \u6CE8\u518C\u6587\u4EF6\u5904\u7406\u5668: " + processor.type);
|
|
3041
3039
|
}
|
|
3042
3040
|
// ============= 核心文件操作方法 =============
|
|
3043
3041
|
/**
|
|
@@ -3046,7 +3044,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3046
3044
|
async uploadFile(fileInfo, storageType, onProgress) {
|
|
3047
3045
|
const fileId = v4();
|
|
3048
3046
|
const startTime = Date.now();
|
|
3049
|
-
logger6.info(
|
|
3047
|
+
logger6.info("\u{1F4E4} [UniversalFileService] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6: " + fileInfo.file.name + ", ID: " + fileId);
|
|
3050
3048
|
try {
|
|
3051
3049
|
await this.validateFile(fileInfo.file);
|
|
3052
3050
|
const progress = {
|
|
@@ -3065,7 +3063,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3065
3063
|
let storageProvider = this.storageProviders.get(selectedStorageType);
|
|
3066
3064
|
if (!storageProvider) {
|
|
3067
3065
|
logger6.info(
|
|
3068
|
-
|
|
3066
|
+
"\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005 " + selectedStorageType + " \u4E0D\u53EF\u7528\uFF0C\u5C1D\u8BD5\u4F7F\u7528OSS"
|
|
3069
3067
|
);
|
|
3070
3068
|
storageProvider = this.storageProviders.get("aliyun-oss");
|
|
3071
3069
|
if (!storageProvider) {
|
|
@@ -3084,7 +3082,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3084
3082
|
this.emitFileEvent("upload:progress", fileId, { progress: progress.progress });
|
|
3085
3083
|
const uploadResult = await storageProvider.upload(fileInfo, storagePath);
|
|
3086
3084
|
if (!uploadResult.success) {
|
|
3087
|
-
throw new FileUploadError(
|
|
3085
|
+
throw new FileUploadError("\u4E0A\u4F20\u5931\u8D25: " + uploadResult.error);
|
|
3088
3086
|
}
|
|
3089
3087
|
metadata.storagePath = uploadResult.path || storagePath;
|
|
3090
3088
|
metadata.storageProvider = selectedStorageType;
|
|
@@ -3107,7 +3105,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3107
3105
|
this.uploadProgressMap.set(fileId, progress);
|
|
3108
3106
|
onProgress?.(progress);
|
|
3109
3107
|
const uploadTime = Date.now() - startTime;
|
|
3110
|
-
logger6.info(
|
|
3108
|
+
logger6.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210: " + fileId + ", \u8017\u65F6: " + uploadTime + "ms");
|
|
3111
3109
|
this.emitFileEvent("upload:complete", fileId, {
|
|
3112
3110
|
fileName: fileInfo.file.name,
|
|
3113
3111
|
size: fileInfo.file.size,
|
|
@@ -3115,7 +3113,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3115
3113
|
});
|
|
3116
3114
|
return metadata;
|
|
3117
3115
|
} catch (error) {
|
|
3118
|
-
console.error(
|
|
3116
|
+
console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: " + fileId + ":", error);
|
|
3119
3117
|
const progress = this.uploadProgressMap.get(fileId);
|
|
3120
3118
|
if (progress) {
|
|
3121
3119
|
progress.status = "failed";
|
|
@@ -3143,27 +3141,27 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3143
3141
|
* 下载文件
|
|
3144
3142
|
*/
|
|
3145
3143
|
async downloadFile(fileId, userId) {
|
|
3146
|
-
logger6.info(
|
|
3144
|
+
logger6.info("\u{1F4E5} [UniversalFileService] \u5F00\u59CB\u4E0B\u8F7D\u6587\u4EF6: " + fileId);
|
|
3147
3145
|
try {
|
|
3148
3146
|
this.emitFileEvent("download:start", fileId);
|
|
3149
3147
|
const metadata = await this.getFileMetadata(fileId);
|
|
3150
3148
|
if (!metadata) {
|
|
3151
|
-
throw new FileUploadError(
|
|
3149
|
+
throw new FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
|
|
3152
3150
|
}
|
|
3153
3151
|
await this.checkFileAccess(metadata, userId);
|
|
3154
3152
|
const storageProvider = this.storageProviders.get(metadata.storageProvider);
|
|
3155
3153
|
if (!storageProvider) {
|
|
3156
|
-
throw new StorageProviderError(
|
|
3154
|
+
throw new StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
|
|
3157
3155
|
}
|
|
3158
3156
|
const fileBuffer = await storageProvider.download(metadata.storagePath);
|
|
3159
3157
|
if (this.config.persistence?.enabled) {
|
|
3160
3158
|
await this.updateAccessStats(fileId);
|
|
3161
3159
|
}
|
|
3162
|
-
logger6.info(
|
|
3160
|
+
logger6.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210: " + fileId);
|
|
3163
3161
|
this.emitFileEvent("download:complete", fileId, { size: fileBuffer.length });
|
|
3164
3162
|
return fileBuffer;
|
|
3165
3163
|
} catch (error) {
|
|
3166
|
-
console.error(
|
|
3164
|
+
console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: " + fileId + ":", error);
|
|
3167
3165
|
this.emitFileEvent("download:error", fileId, void 0, error instanceof Error ? error.message : "\u4E0B\u8F7D\u5931\u8D25");
|
|
3168
3166
|
throw error;
|
|
3169
3167
|
}
|
|
@@ -3172,30 +3170,30 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3172
3170
|
* 删除文件
|
|
3173
3171
|
*/
|
|
3174
3172
|
async deleteFile(fileId, userId) {
|
|
3175
|
-
logger6.info(
|
|
3173
|
+
logger6.info("\u{1F5D1}\uFE0F [UniversalFileService] \u5F00\u59CB\u5220\u9664\u6587\u4EF6: " + fileId);
|
|
3176
3174
|
try {
|
|
3177
3175
|
const metadata = await this.getFileMetadata(fileId);
|
|
3178
3176
|
if (!metadata) {
|
|
3179
|
-
throw new FileUploadError(
|
|
3177
|
+
throw new FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
|
|
3180
3178
|
}
|
|
3181
3179
|
await this.checkFileDeleteAccess(metadata, userId);
|
|
3182
3180
|
const storageProvider = this.storageProviders.get(metadata.storageProvider);
|
|
3183
3181
|
if (!storageProvider) {
|
|
3184
|
-
throw new StorageProviderError(
|
|
3182
|
+
throw new StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
|
|
3185
3183
|
}
|
|
3186
3184
|
const deleteResult = await storageProvider.delete(metadata.storagePath);
|
|
3187
3185
|
if (!deleteResult.success) {
|
|
3188
|
-
console.warn(
|
|
3186
|
+
console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u6587\u4EF6\u5220\u9664\u5931\u8D25: " + deleteResult.error);
|
|
3189
3187
|
}
|
|
3190
3188
|
if (this.config.persistence?.enabled) {
|
|
3191
3189
|
await this.deleteFileMetadata(fileId);
|
|
3192
3190
|
}
|
|
3193
3191
|
this.clearMetadataCache(fileId);
|
|
3194
|
-
logger6.info(
|
|
3192
|
+
logger6.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5B8C\u6210: " + fileId);
|
|
3195
3193
|
this.emitFileEvent("delete:complete", fileId);
|
|
3196
3194
|
this.emit("file:deleted", fileId);
|
|
3197
3195
|
} catch (error) {
|
|
3198
|
-
console.error(
|
|
3196
|
+
console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5931\u8D25: " + fileId + ":", error);
|
|
3199
3197
|
this.emitFileEvent("delete:error", fileId, void 0, error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25");
|
|
3200
3198
|
throw error;
|
|
3201
3199
|
}
|
|
@@ -3204,14 +3202,14 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3204
3202
|
* 获取文件访问URL
|
|
3205
3203
|
*/
|
|
3206
3204
|
async getFileUrl(fileId, userId, expiresIn) {
|
|
3207
|
-
const cacheKey =
|
|
3205
|
+
const cacheKey = fileId + "_" + (userId || "public") + "_" + (expiresIn || 0);
|
|
3208
3206
|
const cached = this.urlCache.get(cacheKey);
|
|
3209
3207
|
if (cached && cached.expires > Date.now()) {
|
|
3210
3208
|
return cached.url;
|
|
3211
3209
|
}
|
|
3212
3210
|
const metadata = await this.getFileMetadata(fileId);
|
|
3213
3211
|
if (!metadata) {
|
|
3214
|
-
throw new FileUploadError(
|
|
3212
|
+
throw new FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
|
|
3215
3213
|
}
|
|
3216
3214
|
await this.checkFileAccess(metadata, userId);
|
|
3217
3215
|
let url;
|
|
@@ -3220,7 +3218,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3220
3218
|
} else {
|
|
3221
3219
|
const storageProvider = this.storageProviders.get(metadata.storageProvider);
|
|
3222
3220
|
if (!storageProvider) {
|
|
3223
|
-
throw new StorageProviderError(
|
|
3221
|
+
throw new StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
|
|
3224
3222
|
}
|
|
3225
3223
|
url = await storageProvider.getAccessUrl(metadata.storagePath, expiresIn);
|
|
3226
3224
|
}
|
|
@@ -3248,7 +3246,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3248
3246
|
return null;
|
|
3249
3247
|
}
|
|
3250
3248
|
}
|
|
3251
|
-
logger6.warn(
|
|
3249
|
+
logger6.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u65E0\u6CD5\u67E5\u8BE2\u6587\u4EF6\u5143\u6570\u636E: " + fileId);
|
|
3252
3250
|
return null;
|
|
3253
3251
|
}
|
|
3254
3252
|
/**
|
|
@@ -3354,7 +3352,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3354
3352
|
if (i === maxRetries - 1) {
|
|
3355
3353
|
throw new Error("OSS\u914D\u7F6E\u52A0\u8F7D\u8D85\u65F6\uFF1A\u7F3A\u5C11\u5FC5\u9700\u7684\u914D\u7F6E\u9879 (accessKeyId, accessKeySecret, bucket, region)");
|
|
3356
3354
|
}
|
|
3357
|
-
logger6.debug(
|
|
3355
|
+
logger6.debug("\u7B49\u5F85OSS\u914D\u7F6E\u52A0\u8F7D\u4E2D... (" + (i + 1) + "/" + maxRetries + ")");
|
|
3358
3356
|
}
|
|
3359
3357
|
}
|
|
3360
3358
|
}
|
|
@@ -3375,12 +3373,12 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3375
3373
|
if (provider) {
|
|
3376
3374
|
try {
|
|
3377
3375
|
await provider.initialize(config);
|
|
3378
|
-
logger6.info(
|
|
3376
|
+
logger6.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: " + type);
|
|
3379
3377
|
} catch (error) {
|
|
3380
|
-
console.warn(
|
|
3378
|
+
console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5931\u8D25: " + type + ":", error);
|
|
3381
3379
|
}
|
|
3382
3380
|
} else {
|
|
3383
|
-
console.warn(
|
|
3381
|
+
console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u6CE8\u518C: " + type);
|
|
3384
3382
|
}
|
|
3385
3383
|
}
|
|
3386
3384
|
}
|
|
@@ -3391,19 +3389,19 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3391
3389
|
try {
|
|
3392
3390
|
if (this.config.storage) {
|
|
3393
3391
|
if (this.config.storage.type === "aliyun-oss" && this.config.storage.enabled) {
|
|
3394
|
-
const { AliyunOSSProvider: AliyunOSSProvider2 } = await import('../../AliyunOSSProvider-
|
|
3392
|
+
const { AliyunOSSProvider: AliyunOSSProvider2 } = await import('../../AliyunOSSProvider-P6TOVKMM.mjs');
|
|
3395
3393
|
const ossProvider = new AliyunOSSProvider2();
|
|
3396
3394
|
this.registerStorageProvider(ossProvider);
|
|
3397
3395
|
logger6.info("\u2705 [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
|
|
3398
3396
|
} else if (this.config.storage.type === "local" && this.config.storage.enabled) {
|
|
3399
|
-
const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-
|
|
3397
|
+
const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-3RVPCQB3.mjs');
|
|
3400
3398
|
const localProvider = new LocalStorageProvider2();
|
|
3401
3399
|
this.registerStorageProvider(localProvider);
|
|
3402
3400
|
logger6.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
|
|
3403
3401
|
}
|
|
3404
3402
|
}
|
|
3405
3403
|
if (this.storageProviders.size === 0) {
|
|
3406
|
-
const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-
|
|
3404
|
+
const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-3RVPCQB3.mjs');
|
|
3407
3405
|
const fallbackProvider = new LocalStorageProvider2();
|
|
3408
3406
|
this.registerStorageProvider(fallbackProvider);
|
|
3409
3407
|
logger6.info("\u2705 [UniversalFileService] \u5DF2\u6CE8\u518C\u5907\u7528\u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005");
|
|
@@ -3415,22 +3413,22 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3415
3413
|
}
|
|
3416
3414
|
async initializeCDNProviders() {
|
|
3417
3415
|
if (this.config.cdn && this.config.cdn.enabled) {
|
|
3418
|
-
logger6.info(
|
|
3416
|
+
logger6.info("\u2705 [UniversalFileService] CDN\u914D\u7F6E\u5DF2\u542F\u7528: " + this.config.cdn.type);
|
|
3419
3417
|
}
|
|
3420
3418
|
}
|
|
3421
3419
|
async initializeFileProcessors() {
|
|
3422
3420
|
for (const processor of Array.from(this.fileProcessors.values())) {
|
|
3423
3421
|
await processor.initialize();
|
|
3424
|
-
logger6.info(
|
|
3422
|
+
logger6.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210: " + processor.type);
|
|
3425
3423
|
}
|
|
3426
3424
|
}
|
|
3427
3425
|
async validateFile(file) {
|
|
3428
3426
|
if (this.config.maxFileSize && file.size > this.config.maxFileSize) {
|
|
3429
|
-
throw new FileUploadError(
|
|
3427
|
+
throw new FileUploadError("\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: " + file.size + " > " + this.config.maxFileSize);
|
|
3430
3428
|
}
|
|
3431
3429
|
const mimeType = file.type || getMimeType(file.name);
|
|
3432
3430
|
if (this.config.allowedMimeTypes && this.config.allowedMimeTypes.length > 0 && !this.config.allowedMimeTypes.includes(mimeType)) {
|
|
3433
|
-
throw new FileUploadError(
|
|
3431
|
+
throw new FileUploadError("\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: " + mimeType);
|
|
3434
3432
|
}
|
|
3435
3433
|
}
|
|
3436
3434
|
async generateFileMetadata(fileId, fileInfo) {
|
|
@@ -3441,7 +3439,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3441
3439
|
return {
|
|
3442
3440
|
id: fileId,
|
|
3443
3441
|
originalName: fileInfo.file.name,
|
|
3444
|
-
storageName:
|
|
3442
|
+
storageName: fileId + extension,
|
|
3445
3443
|
size: fileInfo.file.size,
|
|
3446
3444
|
mimeType,
|
|
3447
3445
|
extension,
|
|
@@ -3462,7 +3460,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3462
3460
|
const year = date.getFullYear();
|
|
3463
3461
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3464
3462
|
const day = String(date.getDate()).padStart(2, "0");
|
|
3465
|
-
return
|
|
3463
|
+
return metadata.moduleId + "/" + year + "/" + month + "/" + day + "/" + metadata.storageName;
|
|
3466
3464
|
}
|
|
3467
3465
|
async generateFileHash(file) {
|
|
3468
3466
|
const buffer = await file.arrayBuffer();
|
|
@@ -3476,7 +3474,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3476
3474
|
}
|
|
3477
3475
|
const processor = this.fileProcessors.get(options.type);
|
|
3478
3476
|
if (!processor) {
|
|
3479
|
-
console.warn(
|
|
3477
|
+
console.warn("\u26A0\uFE0F [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u4E0D\u5B58\u5728: " + options.type);
|
|
3480
3478
|
return;
|
|
3481
3479
|
}
|
|
3482
3480
|
if (this.processingQueue.length >= 1e3) {
|
|
@@ -3497,7 +3495,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3497
3495
|
const basePath = metadata.storagePath;
|
|
3498
3496
|
const extension = path3.extname(basePath);
|
|
3499
3497
|
const basename4 = basePath.replace(extension, "");
|
|
3500
|
-
return
|
|
3498
|
+
return basename4 + "_processed" + extension;
|
|
3501
3499
|
}
|
|
3502
3500
|
async processFileQueue() {
|
|
3503
3501
|
if (this.isProcessingQueueRunning || this.processingQueue.length === 0) {
|
|
@@ -3516,7 +3514,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3516
3514
|
this.emitFileEvent("processing:error", task.fileId, void 0, result.error);
|
|
3517
3515
|
}
|
|
3518
3516
|
} catch (error) {
|
|
3519
|
-
console.error(
|
|
3517
|
+
console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5931\u8D25: " + task.fileId + ":", error);
|
|
3520
3518
|
this.emitFileEvent(
|
|
3521
3519
|
"processing:error",
|
|
3522
3520
|
task.fileId,
|
|
@@ -3560,7 +3558,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3560
3558
|
} catch (error) {
|
|
3561
3559
|
console.error("\u274C [UniversalFileService] \u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
|
|
3562
3560
|
throw new FileUploadError(
|
|
3563
|
-
|
|
3561
|
+
"\u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
3564
3562
|
);
|
|
3565
3563
|
}
|
|
3566
3564
|
}
|
|
@@ -3577,7 +3575,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3577
3575
|
} catch (error) {
|
|
3578
3576
|
console.error("\u274C [UniversalFileService] \u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
|
|
3579
3577
|
throw new FileUploadError(
|
|
3580
|
-
|
|
3578
|
+
"\u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
|
|
3581
3579
|
);
|
|
3582
3580
|
}
|
|
3583
3581
|
}
|
|
@@ -3625,7 +3623,7 @@ var UniversalFileService = class extends EventEmitter {
|
|
|
3625
3623
|
const startTime = Date.now();
|
|
3626
3624
|
while (!this.isFullyInitialized()) {
|
|
3627
3625
|
if (Date.now() - startTime > timeoutMs) {
|
|
3628
|
-
throw new Error(
|
|
3626
|
+
throw new Error("\u670D\u52A1\u521D\u59CB\u5316\u8D85\u65F6 (" + timeoutMs + "ms)");
|
|
3629
3627
|
}
|
|
3630
3628
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3631
3629
|
}
|
|
@@ -3683,7 +3681,7 @@ var CacheManager = class {
|
|
|
3683
3681
|
* 生成缓存键
|
|
3684
3682
|
*/
|
|
3685
3683
|
generateKey(key) {
|
|
3686
|
-
return
|
|
3684
|
+
return this.options.keyPrefix + key;
|
|
3687
3685
|
}
|
|
3688
3686
|
/**
|
|
3689
3687
|
* 获取缓存数据
|
|
@@ -3796,7 +3794,7 @@ var CacheManager = class {
|
|
|
3796
3794
|
try {
|
|
3797
3795
|
this.memoryCache.clear();
|
|
3798
3796
|
if (this.redisClient && this.stats.redisConnected) {
|
|
3799
|
-
const keys = await this.redisClient.keys(
|
|
3797
|
+
const keys = await this.redisClient.keys(this.options.keyPrefix + "*");
|
|
3800
3798
|
if (keys.length > 0) {
|
|
3801
3799
|
await this.redisClient.del(...keys);
|
|
3802
3800
|
}
|
|
@@ -3828,7 +3826,7 @@ var CacheManager = class {
|
|
|
3828
3826
|
* 预热缓存
|
|
3829
3827
|
*/
|
|
3830
3828
|
async warmup(items) {
|
|
3831
|
-
logger7.info(
|
|
3829
|
+
logger7.info("\u5F00\u59CB\u9884\u70ED\u7F13\u5B58\uFF0C\u5171 " + items.length + " \u9879...");
|
|
3832
3830
|
const promises = items.map((item) => this.set(item.key, item.data, item.ttl));
|
|
3833
3831
|
try {
|
|
3834
3832
|
await Promise.all(promises);
|
|
@@ -3854,7 +3852,7 @@ var CacheManager = class {
|
|
|
3854
3852
|
*/
|
|
3855
3853
|
matchPattern(key, pattern) {
|
|
3856
3854
|
const regexPattern = pattern.replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
3857
|
-
const regex = new RegExp(
|
|
3855
|
+
const regex = new RegExp("^" + regexPattern + "$");
|
|
3858
3856
|
return regex.test(key);
|
|
3859
3857
|
}
|
|
3860
3858
|
/**
|
|
@@ -4387,7 +4385,7 @@ var CdnCacheStrategy2 = class {
|
|
|
4387
4385
|
Expires: new Date(Date.now() + strategy.browserCacheTtl * 1e3).toUTCString()
|
|
4388
4386
|
};
|
|
4389
4387
|
if (strategy.browserCache) {
|
|
4390
|
-
headers["ETag"] =
|
|
4388
|
+
headers["ETag"] = '"' + Date.now() + '"';
|
|
4391
4389
|
}
|
|
4392
4390
|
headers["Last-Modified"] = (/* @__PURE__ */ new Date()).toUTCString();
|
|
4393
4391
|
if (strategy.type === "static" /* STATIC */) {
|
|
@@ -4466,7 +4464,7 @@ var CdnCacheStrategy2 = class {
|
|
|
4466
4464
|
if (stats.hitRate < 60) {
|
|
4467
4465
|
suggestions.push({
|
|
4468
4466
|
type,
|
|
4469
|
-
issue:
|
|
4467
|
+
issue: type + "\u7C7B\u578B\u6587\u4EF6\u7F13\u5B58\u547D\u4E2D\u7387\u8FC7\u4F4E (" + stats.hitRate.toFixed(1) + "%)",
|
|
4470
4468
|
suggestion: "\u8003\u8651\u589E\u52A0\u7F13\u5B58\u65F6\u95F4\u6216\u542F\u7528\u9884\u70ED\u673A\u5236",
|
|
4471
4469
|
severity: stats.hitRate < 30 ? "high" : "medium"
|
|
4472
4470
|
});
|
|
@@ -4474,7 +4472,7 @@ var CdnCacheStrategy2 = class {
|
|
|
4474
4472
|
if (stats.estimatedSize > 1024 * 1024 * 1024) {
|
|
4475
4473
|
suggestions.push({
|
|
4476
4474
|
type,
|
|
4477
|
-
issue:
|
|
4475
|
+
issue: type + "\u7C7B\u578B\u6587\u4EF6\u7F13\u5B58\u5360\u7528\u7A7A\u95F4\u8FC7\u5927 (" + (stats.estimatedSize / 1024 / 1024 / 1024).toFixed(2) + "GB)",
|
|
4478
4476
|
suggestion: "\u8003\u8651\u51CF\u5C11\u7F13\u5B58\u65F6\u95F4\u6216\u4F18\u5316\u6587\u4EF6\u538B\u7F29",
|
|
4479
4477
|
severity: "medium"
|
|
4480
4478
|
});
|
|
@@ -4697,13 +4695,13 @@ function createDrizzleRepository(config) {
|
|
|
4697
4695
|
const existing = await db.select().from(table).where(eq(table[getField("id")], metadata.id)).limit(1);
|
|
4698
4696
|
if (existing && existing.length > 0) {
|
|
4699
4697
|
await db.update(table).set(record).where(eq(table[getField("id")], metadata.id));
|
|
4700
|
-
logger8.info(
|
|
4698
|
+
logger8.info("\u2705 [DrizzleRepository] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u66F4\u65B0: " + metadata.id);
|
|
4701
4699
|
} else {
|
|
4702
4700
|
await db.insert(table).values(record);
|
|
4703
|
-
logger8.info(
|
|
4701
|
+
logger8.info("\u2705 [DrizzleRepository] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u63D2\u5165: " + metadata.id);
|
|
4704
4702
|
}
|
|
4705
4703
|
} catch (error) {
|
|
4706
|
-
logger8.error(
|
|
4704
|
+
logger8.error("\u274C [DrizzleRepository] \u4FDD\u5B58\u5931\u8D25: " + metadata.id, error);
|
|
4707
4705
|
throw error;
|
|
4708
4706
|
}
|
|
4709
4707
|
},
|
|
@@ -4715,7 +4713,7 @@ function createDrizzleRepository(config) {
|
|
|
4715
4713
|
}
|
|
4716
4714
|
return toFileMetadata(result[0]);
|
|
4717
4715
|
} catch (error) {
|
|
4718
|
-
logger8.error(
|
|
4716
|
+
logger8.error("\u274C [DrizzleRepository] \u67E5\u8BE2\u5931\u8D25: " + fileId, error);
|
|
4719
4717
|
throw error;
|
|
4720
4718
|
}
|
|
4721
4719
|
},
|
|
@@ -4750,14 +4748,14 @@ function createDrizzleRepository(config) {
|
|
|
4750
4748
|
conditions.push(eq(table[getField("status")], status));
|
|
4751
4749
|
}
|
|
4752
4750
|
if (startDate) {
|
|
4753
|
-
conditions.push(sql
|
|
4751
|
+
conditions.push(sql(table[getField("uploadedAt")]) + " >= " + startDate);
|
|
4754
4752
|
}
|
|
4755
4753
|
if (endDate) {
|
|
4756
|
-
conditions.push(sql
|
|
4754
|
+
conditions.push(sql(table[getField("uploadedAt")]) + " <= " + endDate);
|
|
4757
4755
|
}
|
|
4758
4756
|
if (tags && tags.length > 0) {
|
|
4759
4757
|
for (const tag of tags) {
|
|
4760
|
-
conditions.push(sql
|
|
4758
|
+
conditions.push(sql(table[getField("tags")]) + " @> " + JSON.stringify([tag]));
|
|
4761
4759
|
}
|
|
4762
4760
|
}
|
|
4763
4761
|
const countResult = await db.select({ count: sql`count(*)` }).from(table).where(conditions.length > 0 ? and(...conditions) : void 0);
|
|
@@ -4780,17 +4778,17 @@ function createDrizzleRepository(config) {
|
|
|
4780
4778
|
async delete(fileId) {
|
|
4781
4779
|
try {
|
|
4782
4780
|
await db.delete(table).where(eq(table[getField("id")], fileId));
|
|
4783
|
-
logger8.info(
|
|
4781
|
+
logger8.info("\u{1F5D1}\uFE0F [DrizzleRepository] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u5220\u9664: " + fileId);
|
|
4784
4782
|
} catch (error) {
|
|
4785
|
-
logger8.error(
|
|
4783
|
+
logger8.error("\u274C [DrizzleRepository] \u5220\u9664\u5931\u8D25: " + fileId, error);
|
|
4786
4784
|
throw error;
|
|
4787
4785
|
}
|
|
4788
4786
|
},
|
|
4789
4787
|
async batchDelete(fileIds) {
|
|
4790
4788
|
try {
|
|
4791
4789
|
if (fileIds.length === 0) return;
|
|
4792
|
-
await db.delete(table).where(sql
|
|
4793
|
-
logger8.info(
|
|
4790
|
+
await db.delete(table).where(sql(table[getField("id")]) + " = ANY(" + fileIds + ")");
|
|
4791
|
+
logger8.info("\u{1F5D1}\uFE0F [DrizzleRepository] \u6279\u91CF\u5220\u9664\u6210\u529F: " + fileIds.length + " \u4E2A\u6587\u4EF6");
|
|
4794
4792
|
} catch (error) {
|
|
4795
4793
|
logger8.error(`\u274C [DrizzleRepository] \u6279\u91CF\u5220\u9664\u5931\u8D25`, error);
|
|
4796
4794
|
throw error;
|
|
@@ -4938,7 +4936,7 @@ function loadConfigFromEnv() {
|
|
|
4938
4936
|
const cdnConfig = loadCDNConfigFromEnv();
|
|
4939
4937
|
const storage = ossConfig || getDefaultLocalStorage();
|
|
4940
4938
|
const defaultStorage = ossConfig ? "aliyun-oss" : "local";
|
|
4941
|
-
logger9.info(
|
|
4939
|
+
logger9.info("\u4F7F\u7528\u5B58\u50A8\u65B9\u5F0F: " + defaultStorage);
|
|
4942
4940
|
const config = {
|
|
4943
4941
|
storage,
|
|
4944
4942
|
defaultStorage,
|