sa2kit 1.6.24 → 1.6.26

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.
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ var chunkBLQRF7C7_js = require('./chunk-BLQRF7C7.js');
4
+ require('./chunk-KH6RQ4J5.js');
5
+ require('./chunk-6PRFP5EG.js');
6
+ require('./chunk-DGUM43GV.js');
7
+
8
+
9
+
10
+ Object.defineProperty(exports, "AliyunOSSProvider", {
11
+ enumerable: true,
12
+ get: function () { return chunkBLQRF7C7_js.AliyunOSSProvider; }
13
+ });
14
+ //# sourceMappingURL=AliyunOSSProvider-KOVWJQLL.js.map
15
+ //# sourceMappingURL=AliyunOSSProvider-KOVWJQLL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"AliyunOSSProvider-XCTK3QQA.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"AliyunOSSProvider-KOVWJQLL.js"}
@@ -0,0 +1,6 @@
1
+ export { AliyunOSSProvider } from './chunk-SWWRT5FN.mjs';
2
+ import './chunk-ZGVB35L2.mjs';
3
+ import './chunk-KQGP6BTS.mjs';
4
+ import './chunk-BJTO5JO5.mjs';
5
+ //# sourceMappingURL=AliyunOSSProvider-YKT256D6.mjs.map
6
+ //# sourceMappingURL=AliyunOSSProvider-YKT256D6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"AliyunOSSProvider-2UZRIGT3.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"AliyunOSSProvider-YKT256D6.mjs"}
@@ -476,6 +476,10 @@ declare class UniversalFileService extends EventEmitter {
476
476
  * 移除文件事件监听器
477
477
  */
478
478
  offFileEvent(eventType: string, listener: FileEventListener$1): void;
479
+ /**
480
+ * 验证配置是否完整
481
+ */
482
+ private validateConfiguration;
479
483
  private initializeStorageProviders;
480
484
  private registerDefaultStorageProviders;
481
485
  private initializeCDNProviders;
@@ -510,6 +514,14 @@ declare class UniversalFileService extends EventEmitter {
510
514
  * 检查文件删除权限
511
515
  */
512
516
  private checkFileDeleteAccess;
517
+ /**
518
+ * 检查服务是否完全可用(包括存储提供者)
519
+ */
520
+ isFullyInitialized(): boolean;
521
+ /**
522
+ * 等待服务完全初始化(带超时)
523
+ */
524
+ waitForInitialization(timeoutMs?: number): Promise<void>;
513
525
  }
514
526
 
515
527
  export { type AliyunOSSConfig as A, CDNProviderError as B, type CDNType as C, type FileServicePersistenceConfig as F, type IStorageProvider as I, type LocalStorageConfig as L, type ProcessorType as P, type StorageConfig as S, UniversalFileService as U, type UniversalFileServiceConfig as a, type StorageType as b, type UploadFileInfo as c, type StorageResult as d, type ICDNProvider as e, type CDNConfig as f, type CDNResult as g, type IFileProcessor as h, type ProcessingOptions as i, type ProcessingResult as j, type IFileMetadataRepository as k, type AliyunCDNConfig as l, type CacheConfig as m, type StorageMetadata as n, type CDNStats as o, type ProcessorInfo as p, type FileRecord as q, type FileQueryOptions as r, type PaginatedResult as s, type FileEvent as t, type FileEventListener as u, type FileEventType as v, FileServiceError as w, FileUploadError as x, FileProcessingError as y, StorageProviderError as z };
@@ -476,6 +476,10 @@ declare class UniversalFileService extends EventEmitter {
476
476
  * 移除文件事件监听器
477
477
  */
478
478
  offFileEvent(eventType: string, listener: FileEventListener$1): void;
479
+ /**
480
+ * 验证配置是否完整
481
+ */
482
+ private validateConfiguration;
479
483
  private initializeStorageProviders;
480
484
  private registerDefaultStorageProviders;
481
485
  private initializeCDNProviders;
@@ -510,6 +514,14 @@ declare class UniversalFileService extends EventEmitter {
510
514
  * 检查文件删除权限
511
515
  */
512
516
  private checkFileDeleteAccess;
517
+ /**
518
+ * 检查服务是否完全可用(包括存储提供者)
519
+ */
520
+ isFullyInitialized(): boolean;
521
+ /**
522
+ * 等待服务完全初始化(带超时)
523
+ */
524
+ waitForInitialization(timeoutMs?: number): Promise<void>;
513
525
  }
514
526
 
515
527
  export { type AliyunOSSConfig as A, CDNProviderError as B, type CDNType as C, type FileServicePersistenceConfig as F, type IStorageProvider as I, type LocalStorageConfig as L, type ProcessorType as P, type StorageConfig as S, UniversalFileService as U, type UniversalFileServiceConfig as a, type StorageType as b, type UploadFileInfo as c, type StorageResult as d, type ICDNProvider as e, type CDNConfig as f, type CDNResult as g, type IFileProcessor as h, type ProcessingOptions as i, type ProcessingResult as j, type IFileMetadataRepository as k, type AliyunCDNConfig as l, type CacheConfig as m, type StorageMetadata as n, type CDNStats as o, type ProcessorInfo as p, type FileRecord as q, type FileQueryOptions as r, type PaginatedResult as s, type FileEvent as t, type FileEventListener as u, type FileEventType as v, FileServiceError as w, FileUploadError as x, FileProcessingError as y, StorageProviderError as z };
@@ -42,8 +42,31 @@ var AliyunOSSProvider = class {
42
42
  }
43
43
  this.config = newConfig;
44
44
  logger.info(`\u2601\uFE0F [AliyunOSSProvider] ${this.isInitialized ? "\u91CD\u65B0" : ""}\u521D\u59CB\u5316\u963F\u91CC\u4E91OSS`);
45
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] ${this.config ? JSON.stringify(this.config) : ""}`);
45
46
  try {
46
47
  this.validateConfig();
48
+ if (!this.config.region || typeof this.config.region !== "string") {
49
+ throw new Error("OSS region \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
50
+ }
51
+ if (!this.config.bucket || typeof this.config.bucket !== "string") {
52
+ throw new Error("OSS bucket \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
53
+ }
54
+ if (!this.config.accessKeyId || typeof this.config.accessKeyId !== "string") {
55
+ throw new Error("OSS accessKeyId \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
56
+ }
57
+ if (!this.config.accessKeySecret || typeof this.config.accessKeySecret !== "string") {
58
+ throw new Error("OSS accessKeySecret \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
59
+ }
60
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] \u521B\u5EFAOSS\u5BA2\u6237\u7AEF\u914D\u7F6E:`, {
61
+ region: this.config.region,
62
+ bucket: this.config.bucket,
63
+ hasAccessKeyId: !!this.config.accessKeyId,
64
+ hasAccessKeySecret: !!this.config.accessKeySecret,
65
+ secure: this.config.secure !== false,
66
+ internal: this.config.internal || false,
67
+ cname: !!this.config.customDomain,
68
+ endpoint: this.config.customDomain || "\u9ED8\u8BA4\u7AEF\u70B9"
69
+ });
47
70
  this.client = new OSS__default.default({
48
71
  region: this.config.region,
49
72
  bucket: this.config.bucket,
@@ -59,6 +82,11 @@ var AliyunOSSProvider = class {
59
82
  // 是否使用自定义域名
60
83
  endpoint: this.config.customDomain || void 0
61
84
  });
85
+ if (!this.client) {
86
+ throw new Error("OSS\u5BA2\u6237\u7AEF\u521B\u5EFA\u5931\u8D25");
87
+ }
88
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] OSS\u5BA2\u6237\u7AEF\u521B\u5EFA\u6210\u529F`);
89
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] \u6D4B\u8BD5\u8FDE\u63A5... testConnection`);
62
90
  await this.testConnection();
63
91
  this.isInitialized = true;
64
92
  logger.info(`\u2705 [AliyunOSSProvider] \u963F\u91CC\u4E91OSS${configChanged ? "\u91CD\u65B0" : ""}\u521D\u59CB\u5316\u5B8C\u6210`);
@@ -351,18 +379,28 @@ var AliyunOSSProvider = class {
351
379
  });
352
380
  logger.info(`\u2705 [AliyunOSSProvider] OSS\u8FDE\u63A5\u6D4B\u8BD5\u6210\u529F`);
353
381
  } catch (error) {
354
- if (this.isOSSError(error)) {
355
- if (error.code === "NoSuchBucket") {
382
+ logger.error("\u274C [AliyunOSSProvider] OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25\uFF0C\u539F\u59CB\u9519\u8BEF:", error);
383
+ let errorCode;
384
+ let errorMessage = "\u672A\u77E5\u9519\u8BEF";
385
+ try {
386
+ errorCode = error?.code;
387
+ errorMessage = error?.message || "\u672A\u77E5\u9519\u8BEF";
388
+ } catch (accessError) {
389
+ logger.warn("\u65E0\u6CD5\u8BBF\u95EE\u9519\u8BEF\u5BF9\u8C61\u7684\u5C5E\u6027:", accessError);
390
+ errorMessage = "\u65E0\u6CD5\u89E3\u6790\u9519\u8BEF\u4FE1\u606F";
391
+ }
392
+ if (typeof errorCode === "string") {
393
+ if (errorCode === "NoSuchBucket") {
356
394
  throw new chunkKH6RQ4J5_js.StorageProviderError(`\u5B58\u50A8\u6876\u4E0D\u5B58\u5728: ${this.config.bucket}`);
357
- }
358
- if (error.code === "InvalidAccessKeyId") {
395
+ } else if (errorCode === "InvalidAccessKeyId") {
359
396
  throw new chunkKH6RQ4J5_js.StorageProviderError("Access Key ID \u65E0\u6548");
360
- }
361
- if (error.code === "SignatureDoesNotMatch") {
397
+ } else if (errorCode === "SignatureDoesNotMatch") {
362
398
  throw new chunkKH6RQ4J5_js.StorageProviderError("Access Key Secret \u65E0\u6548");
399
+ } else {
400
+ throw new chunkKH6RQ4J5_js.StorageProviderError(`OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25: ${errorCode} - ${errorMessage}`);
363
401
  }
364
402
  }
365
- throw error;
403
+ throw new chunkKH6RQ4J5_js.StorageProviderError(`OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25: ${errorMessage}`);
366
404
  }
367
405
  }
368
406
  /**
@@ -415,16 +453,26 @@ var AliyunOSSProvider = class {
415
453
  * 判断是否为OSS错误
416
454
  */
417
455
  isOSSError(error) {
418
- return error && typeof error.code === "string" && typeof error.name === "string";
456
+ if (!error || typeof error !== "object") {
457
+ return false;
458
+ }
459
+ return typeof error.code === "string" && typeof (error.name || "") === "string" && typeof (error.message || "") === "string";
419
460
  }
420
461
  /**
421
462
  * 格式化OSS错误信息
422
463
  */
423
464
  formatOSSError(error) {
424
465
  if (this.isOSSError(error)) {
425
- return `${error.code}: ${error.message}${error.requestId ? ` (RequestId: ${error.requestId})` : ""}`;
466
+ const requestId = error.requestId ? ` (RequestId: ${error.requestId})` : "";
467
+ return `${error.code}: ${error.message}${requestId}`;
468
+ }
469
+ if (error instanceof Error) {
470
+ return error.message;
471
+ }
472
+ if (typeof error === "string") {
473
+ return error;
426
474
  }
427
- return error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF";
475
+ return "\u672A\u77E5\u9519\u8BEF";
428
476
  }
429
477
  /**
430
478
  * 流式上传(可选实现)
@@ -536,5 +584,5 @@ var AliyunOSSProvider = class {
536
584
  };
537
585
 
538
586
  exports.AliyunOSSProvider = AliyunOSSProvider;
539
- //# sourceMappingURL=chunk-EXT3IKQA.js.map
540
- //# sourceMappingURL=chunk-EXT3IKQA.js.map
587
+ //# sourceMappingURL=chunk-BLQRF7C7.js.map
588
+ //# sourceMappingURL=chunk-BLQRF7C7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/universalFile/server/providers/AliyunOSSProvider.ts"],"names":["createLogger","StorageProviderError","OSS"],"mappings":"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","file":"chunk-BLQRF7C7.js","sourcesContent":["/**\n * 阿里云OSS存储提供者实现\n */\n\nimport OSS from 'ali-oss';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IStorageProvider,\n StorageConfig,\n AliyunOSSConfig,\n StorageResult,\n UploadFileInfo,\n StorageType,\n} from '../types';\n\nimport { StorageProviderError } from '../types';\n\nconst logger = createLogger('AliyunOSSProvider');\n\n/**\n * 阿里云OSS存储提供者\n */\nexport class AliyunOSSProvider implements IStorageProvider {\n readonly type: StorageType = 'aliyun-oss';\n\n private config: AliyunOSSConfig | null = null;\n private client: any = null;\n private isInitialized = false;\n\n /**\n * 初始化存储提供者\n */\n async initialize(config: StorageConfig): Promise<void> {\n return this.reinitialize(config);\n }\n\n /**\n * 重新初始化存储提供者(支持配置热更新)\n */\n async reinitialize(config: StorageConfig): Promise<void> {\n if (config.type !== 'aliyun-oss') {\n throw new StorageProviderError('配置类型不匹配:期望 aliyun-oss');\n }\n\n const newConfig = config as AliyunOSSConfig;\n\n // 检查配置是否发生变化\n const configChanged =\n !this.config ||\n this.config.region !== newConfig.region ||\n this.config.bucket !== newConfig.bucket ||\n this.config.accessKeyId !== newConfig.accessKeyId ||\n this.config.accessKeySecret !== newConfig.accessKeySecret ||\n this.config.customDomain !== newConfig.customDomain ||\n this.config.secure !== newConfig.secure ||\n this.config.internal !== newConfig.internal;\n\n if (configChanged) {\n logger.info('🔄 [AliyunOSSProvider] 检测到配置变化,重新初始化OSS客户端');\n logger.info(\n `☁️ [AliyunOSSProvider] 新配置: bucket=${newConfig.bucket}, region=${newConfig.region}`\n );\n } else if (this.isInitialized) {\n logger.info('ℹ️ [AliyunOSSProvider] 配置未变化,跳过重新初始化');\n return;\n }\n\n this.config = newConfig;\n\n logger.info(`☁️ [AliyunOSSProvider] ${this.isInitialized ? '重新' : ''}初始化阿里云OSS`);\n logger.info(`☁️ [AliyunOSSProvider] ${this.config ? JSON.stringify(this.config) : ''}`);\n\n try {\n // 验证必需的配置项\n this.validateConfig();\n\n // 确保配置值是有效的字符串\n if (!this.config.region || typeof this.config.region !== 'string') {\n throw new Error('OSS region 必须是有效的字符串');\n }\n if (!this.config.bucket || typeof this.config.bucket !== 'string') {\n throw new Error('OSS bucket 必须是有效的字符串');\n }\n if (!this.config.accessKeyId || typeof this.config.accessKeyId !== 'string') {\n throw new Error('OSS accessKeyId 必须是有效的字符串');\n }\n if (!this.config.accessKeySecret || typeof this.config.accessKeySecret !== 'string') {\n throw new Error('OSS accessKeySecret 必须是有效的字符串');\n }\n\n logger.info(`☁️ [AliyunOSSProvider] 创建OSS客户端配置:`, {\n region: this.config.region,\n bucket: this.config.bucket,\n hasAccessKeyId: !!this.config.accessKeyId,\n hasAccessKeySecret: !!this.config.accessKeySecret,\n secure: this.config.secure !== false,\n internal: this.config.internal || false,\n cname: !!this.config.customDomain,\n endpoint: this.config.customDomain || '默认端点',\n });\n\n // 创建OSS客户端\n this.client = new OSS({\n region: this.config.region,\n bucket: this.config.bucket,\n accessKeyId: this.config.accessKeyId,\n accessKeySecret: this.config.accessKeySecret,\n secure: this.config.secure !== false, // 默认使用HTTPS\n internal: this.config.internal || false, // 默认使用公网\n timeout: 300000, // 5分钟超时\n cname: !!this.config.customDomain, // 是否使用自定义域名\n endpoint: this.config.customDomain || undefined,\n });\n\n if (!this.client) {\n throw new Error('OSS客户端创建失败');\n }\n\n logger.info(`☁️ [AliyunOSSProvider] OSS客户端创建成功`);\n logger.info(`☁️ [AliyunOSSProvider] 测试连接... testConnection`);\n\n // 测试连接\n await this.testConnection();\n\n this.isInitialized = true;\n logger.info(`✅ [AliyunOSSProvider] 阿里云OSS${configChanged ? '重新' : ''}初始化完成`);\n } catch (error) {\n logger.error('❌ [AliyunOSSProvider] 阿里云OSS初始化失败:', error);\n throw new StorageProviderError(\n `阿里云OSS初始化失败: ${error instanceof Error ? error.message : '未知错误'}`\n );\n }\n }\n\n /**\n * 上传文件\n */\n async upload(fileInfo: UploadFileInfo, filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [AliyunOSSProvider] 开始上传文件到OSS: ${filePath}`);\n\n try {\n // 将File对象转换为Buffer\n const buffer = Buffer.from(await fileInfo.file.arrayBuffer());\n\n // 构建上传选项\n const options: any = {\n headers: {\n 'Content-Type': fileInfo.file.type || 'application/octet-stream',\n 'Content-Length': fileInfo.file.size.toString(),\n },\n meta: {\n uid: 0, // 必需字段\n pid: 0, // 必需字段\n originalName: encodeURIComponent(fileInfo.file.name),\n moduleId: fileInfo.moduleId,\n businessId: fileInfo.businessId || '',\n uploadTime: new Date().toISOString(),\n // 对元数据进行编码处理,避免中文字符问题\n ...this.encodeMetadata(fileInfo.metadata || {}),\n },\n };\n\n // 根据文件大小选择上传方式\n let result: any;\n\n if (fileInfo.file.size > 100 * 1024 * 1024) {\n // 大于100MB使用分片上传\n logger.info(\n `📦 [AliyunOSSProvider] 使用分片上传大文件: ${filePath}, 大小: ${fileInfo.file.size}`\n );\n result = await this.multipartUpload(filePath, buffer, options);\n } else {\n logger.info(\n `📤 [AliyunOSSProvider] 使用普通上传: ${filePath}, 大小: ${fileInfo.file.size}`\n );\n result = await this.client.put(filePath, buffer, options);\n }\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(`✅ [AliyunOSSProvider] 文件上传完成: ${filePath}, 耗时: ${uploadTime}ms`);\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: fileInfo.file.size,\n data: {\n etag: result.data ? JSON.stringify(result.data) : '',\n requestId: result.res?.rt || 0,\n uploadTime,\n ossUrl: result.url || result.name,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 下载文件\n */\n async download(filePath: string): Promise<Buffer> {\n this.ensureInitialized();\n\n logger.info(`📥 [AliyunOSSProvider] 开始从OSS下载文件: ${filePath}`);\n\n try {\n const result = await this.client.get(filePath);\n\n if (!result.content || !Buffer.isBuffer(result.content)) {\n throw new StorageProviderError('下载的文件内容格式错误');\n }\n\n logger.info(\n `✅ [AliyunOSSProvider] 文件下载完成: ${filePath}, 大小: ${result.content.length}`\n );\n\n return result.content;\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件下载失败: ${filePath}:`, error);\n\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n throw new StorageProviderError(`文件不存在: ${filePath}`);\n }\n\n throw new StorageProviderError(`文件下载失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 删除文件\n */\n async delete(filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`🗑️ [AliyunOSSProvider] 开始从OSS删除文件: ${filePath}`);\n\n try {\n const result = await this.client.delete(filePath);\n\n logger.info(`✅ [AliyunOSSProvider] 文件删除完成: ${filePath}`);\n\n return {\n success: true,\n data: {\n requestId: result.res?.rt || 0,\n deletedPath: filePath,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件删除失败: ${filePath}:`, error);\n\n // OSS中删除不存在的文件不会报错,但我们统一处理\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n logger.warn(`⚠️ [AliyunOSSProvider] 文件不存在: ${filePath}`);\n return {\n success: true,\n data: { reason: 'file_not_exists' },\n };\n }\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 获取文件信息\n */\n async getFileInfo(filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n try {\n const result = await this.client.head(filePath);\n\n return {\n success: true,\n size: parseInt(String(result.meta['content-length'] || '0')),\n data: {\n etag: result.meta.etag || '',\n lastModified: result.meta['last-modified'] || '',\n contentType: result.meta['content-type'],\n meta: result.meta,\n size: parseInt(String(result.meta['content-length'] || '0')),\n },\n };\n } catch (error) {\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n return {\n success: false,\n error: '文件不存在',\n };\n }\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 生成访问URL\n */\n async getAccessUrl(filePath: string, expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n try {\n // 对于图片文件,直接返回公开URL,避免CORS问题\n // 对于其他文件,使用签名URL\n const isImage = /\\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)$/i.test(filePath);\n\n if (isImage) {\n // 图片文件使用公开URL\n return this.generateAccessUrl(filePath);\n } else {\n // 其他文件使用签名URL\n const expires = expiresIn || 3600; // 默认1小时\n const signedUrl = this.client.signatureUrl(filePath, {\n expires,\n method: 'GET',\n });\n\n return signedUrl;\n }\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 生成访问URL失败: ${filePath}:`, error);\n throw new StorageProviderError(`生成访问URL失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 生成预签名上传URL\n */\n async getUploadUrl(filePath: string, expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n try {\n const expires = expiresIn || 3600; // 默认1小时\n const signedUrl = this.client.signatureUrl(filePath, {\n expires,\n method: 'PUT',\n });\n\n return signedUrl;\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 生成上传URL失败: ${filePath}:`, error);\n throw new StorageProviderError(`生成上传URL失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 检查文件是否存在\n */\n async exists(filePath: string): Promise<boolean> {\n this.ensureInitialized();\n\n try {\n await this.client.head(filePath);\n return true;\n } catch (error) {\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n return false;\n }\n // 其他错误也视为文件不存在\n logger.warn(`⚠️ [AliyunOSSProvider] 检查文件存在性时出错: ${filePath}:`, error);\n return false;\n }\n }\n\n /**\n * 列出文件(详细信息)\n */\n async listFiles(prefix: string, delimiter: string = '/', maxKeys: number = 1000): Promise<{\n files: Array<{\n name: string;\n url: string;\n size: number;\n lastModified: string;\n etag: string;\n type: string;\n }>;\n folders: string[];\n nextMarker?: string;\n }> {\n this.ensureInitialized();\n\n try {\n const options: any = {\n prefix,\n delimiter,\n 'max-keys': String(maxKeys),\n };\n\n const result = await this.client.list(options);\n\n const files = (result.objects || []).map((obj: any) => ({\n name: obj.name,\n url: this.generateAccessUrl(obj.name),\n size: obj.size,\n lastModified: obj.lastModified,\n etag: obj.etag,\n type: 'file',\n }));\n\n const folders = result.prefixes || [];\n\n return {\n files,\n folders,\n nextMarker: result.nextMarker,\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 列出文件失败: ${prefix}:`, error);\n throw new StorageProviderError(`列出文件失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 列出文件\n */\n async list(prefix: string, maxKeys?: number): Promise<string[]> {\n this.ensureInitialized();\n\n try {\n const options: any = {\n prefix,\n 'max-keys': String(maxKeys || 1000),\n };\n\n const result = await this.client.list(options);\n\n return result.objects?.map((obj: any) => obj.name) || [];\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 列出文件失败: ${prefix}:`, error);\n return [];\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.client || !this.config) {\n throw new StorageProviderError('OSS存储提供者未初始化');\n }\n }\n\n /**\n * 验证配置\n */\n private validateConfig(): void {\n if (!this.config) {\n throw new StorageProviderError('OSS配置为空');\n }\n\n const required = ['region', 'bucket', 'accessKeyId', 'accessKeySecret'];\n const missing = required.filter((key) => !this.config![key as keyof AliyunOSSConfig]);\n\n if (missing.length > 0) {\n throw new StorageProviderError(`OSS配置缺少必需项: ${missing.join(', ')}`);\n }\n }\n\n /**\n * 测试连接\n */\n private async testConnection(): Promise<void> {\n try {\n // 尝试列出少量对象来测试连接\n await this.client.list({\n 'max-keys': '1',\n });\n logger.info(`✅ [AliyunOSSProvider] OSS连接测试成功`);\n } catch (error: any) {\n logger.error('❌ [AliyunOSSProvider] OSS连接测试失败,原始错误:', error);\n\n // 安全地检查错误类型,避免生产环境中的压缩问题\n let errorCode: string | undefined;\n let errorMessage: string = '未知错误';\n\n try {\n errorCode = error?.code;\n errorMessage = error?.message || '未知错误';\n } catch (accessError) {\n // 如果访问错误属性失败,使用通用错误信息\n logger.warn('无法访问错误对象的属性:', accessError);\n errorMessage = '无法解析错误信息';\n }\n\n if (typeof errorCode === 'string') {\n if (errorCode === 'NoSuchBucket') {\n throw new StorageProviderError(`存储桶不存在: ${this.config!.bucket}`);\n }\n else if (errorCode === 'InvalidAccessKeyId') {\n throw new StorageProviderError('Access Key ID 无效');\n }\n else if (errorCode === 'SignatureDoesNotMatch') {\n throw new StorageProviderError('Access Key Secret 无效');\n }\n else {\n throw new StorageProviderError(`OSS连接测试失败: ${errorCode} - ${errorMessage}`);\n }\n }\n\n // 如果不是标准的OSS错误,抛出通用错误\n throw new StorageProviderError(`OSS连接测试失败: ${errorMessage}`);\n }\n }\n\n /**\n * 分片上传大文件\n */\n private async multipartUpload(filePath: string, buffer: Buffer, options: any): Promise<any> {\n logger.info(`📦 [AliyunOSSProvider] 使用多分片上传`);\n\n // 使用OSS的multipartUpload方法\n const result = await this.client.multipartUpload(filePath, buffer, {\n partSize: 10 * 1024 * 1024, // 10MB per chunk\n parallel: 4, // 并发数\n progress: (p: number) => {\n if (p % 0.1 < 0.01) {\n // 每10%显示一次进度\n logger.info(`📦 [AliyunOSSProvider] 上传进度: ${(p * 100).toFixed(1)}%`);\n }\n },\n meta: options.meta,\n headers: options.headers,\n });\n\n return {\n name: result.name,\n url: result.name, // OSS返回的是object名称\n data: result.data,\n res: result.res,\n };\n }\n\n /**\n * 生成公开访问URL\n */\n private generateAccessUrl(filePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('OSS配置为空');\n }\n\n // 确保文件路径不以斜杠开头\n const normalizedPath = filePath.startsWith('/') ? filePath.substring(1) : filePath;\n\n if (this.config.customDomain) {\n // 使用自定义域名\n const protocol = this.config.secure !== false ? 'https' : 'http';\n const url = `${protocol}://${this.config.customDomain}/${normalizedPath}`;\n logger.info(`🔗 [AliyunOSSProvider] 使用自定义域名: ${url}`);\n return url;\n } else {\n // 使用默认OSS域名\n const protocol = this.config.secure !== false ? 'https' : 'http';\n const url = `${protocol}://${this.config.bucket}.${this.config.region}.aliyuncs.com/${normalizedPath}`;\n logger.info(`🔗 [AliyunOSSProvider] 使用默认OSS域名: ${url}`);\n return url;\n }\n }\n\n /**\n * 判断是否为OSS错误\n */\n private isOSSError(\n error: any\n ): error is { code: string; name: string; message: string; requestId?: string } {\n // 安全地检查错误属性,避免生产环境中的压缩问题\n if (!error || typeof error !== 'object') {\n return false;\n }\n\n return typeof error.code === 'string' &&\n typeof (error.name || '') === 'string' &&\n typeof (error.message || '') === 'string';\n }\n\n /**\n * 格式化OSS错误信息\n */\n private formatOSSError(error: any): string {\n if (this.isOSSError(error)) {\n const requestId = error.requestId ? ` (RequestId: ${error.requestId})` : '';\n return `${error.code}: ${error.message}${requestId}`;\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return '未知错误';\n }\n\n /**\n * 流式上传(可选实现)\n */\n async uploadStream(\n readableStream: NodeJS.ReadableStream,\n filePath: string,\n contentType?: string,\n contentLength?: number\n ): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [AliyunOSSProvider] 开始流式上传文件到OSS: ${filePath}`);\n\n try {\n const options: any = {\n timeout: 300000,\n mime: contentType || 'application/octet-stream',\n meta: { uid: 0, pid: 0 },\n callback: { url: '', body: '' },\n headers: {} as any,\n };\n\n if (contentLength) {\n options.headers['Content-Length'] = contentLength.toString();\n }\n\n const result = await this.client.putStream(filePath, readableStream, options);\n\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(`✅ [AliyunOSSProvider] 流式上传完成: ${filePath}, 耗时: ${uploadTime}ms`);\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: contentLength,\n data: {\n name: result.name,\n requestId: result.res?.rt || 0,\n uploadTime,\n ossUrl: result.url || result.name,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 流式上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 批量删除文件\n */\n async batchDelete(filePaths: string[]): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`🗑️ [AliyunOSSProvider] 开始批量删除文件,数量: ${filePaths.length}`);\n\n try {\n const result = await this.client.deleteMulti(filePaths, {\n quiet: false, // 返回删除结果\n });\n\n logger.info(`✅ [AliyunOSSProvider] 批量删除完成,成功: ${result.deleted?.length || 0}`);\n\n return {\n success: true,\n data: {\n deleted: result.deleted,\n requestId: result.res?.rt || 0,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 批量删除失败:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 复制文件\n */\n async copy(sourcePath: string, targetPath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`📋 [AliyunOSSProvider] 开始复制文件: ${sourcePath} -> ${targetPath}`);\n\n try {\n const result = await this.client.copy(targetPath, sourcePath);\n\n logger.info(`✅ [AliyunOSSProvider] 文件复制完成: ${sourcePath} -> ${targetPath}`);\n\n return {\n success: true,\n data: {\n etag: result.data?.etag,\n lastModified: result.data?.lastModified,\n requestId: result.res?.rt || 0,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件复制失败: ${sourcePath} -> ${targetPath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 编码元数据,避免中文字符在HTTP头部中的问题\n */\n private encodeMetadata(metadata: Record<string, any>): Record<string, string> {\n const encoded: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== null && value !== undefined) {\n // 将值转换为字符串并进行URL编码\n const stringValue = String(value);\n encoded[key] = encodeURIComponent(stringValue);\n }\n }\n\n return encoded;\n }\n}\n\n"]}
@@ -36,8 +36,31 @@ var AliyunOSSProvider = class {
36
36
  }
37
37
  this.config = newConfig;
38
38
  logger.info(`\u2601\uFE0F [AliyunOSSProvider] ${this.isInitialized ? "\u91CD\u65B0" : ""}\u521D\u59CB\u5316\u963F\u91CC\u4E91OSS`);
39
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] ${this.config ? JSON.stringify(this.config) : ""}`);
39
40
  try {
40
41
  this.validateConfig();
42
+ if (!this.config.region || typeof this.config.region !== "string") {
43
+ throw new Error("OSS region \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
44
+ }
45
+ if (!this.config.bucket || typeof this.config.bucket !== "string") {
46
+ throw new Error("OSS bucket \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
47
+ }
48
+ if (!this.config.accessKeyId || typeof this.config.accessKeyId !== "string") {
49
+ throw new Error("OSS accessKeyId \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
50
+ }
51
+ if (!this.config.accessKeySecret || typeof this.config.accessKeySecret !== "string") {
52
+ throw new Error("OSS accessKeySecret \u5FC5\u987B\u662F\u6709\u6548\u7684\u5B57\u7B26\u4E32");
53
+ }
54
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] \u521B\u5EFAOSS\u5BA2\u6237\u7AEF\u914D\u7F6E:`, {
55
+ region: this.config.region,
56
+ bucket: this.config.bucket,
57
+ hasAccessKeyId: !!this.config.accessKeyId,
58
+ hasAccessKeySecret: !!this.config.accessKeySecret,
59
+ secure: this.config.secure !== false,
60
+ internal: this.config.internal || false,
61
+ cname: !!this.config.customDomain,
62
+ endpoint: this.config.customDomain || "\u9ED8\u8BA4\u7AEF\u70B9"
63
+ });
41
64
  this.client = new OSS({
42
65
  region: this.config.region,
43
66
  bucket: this.config.bucket,
@@ -53,6 +76,11 @@ var AliyunOSSProvider = class {
53
76
  // 是否使用自定义域名
54
77
  endpoint: this.config.customDomain || void 0
55
78
  });
79
+ if (!this.client) {
80
+ throw new Error("OSS\u5BA2\u6237\u7AEF\u521B\u5EFA\u5931\u8D25");
81
+ }
82
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] OSS\u5BA2\u6237\u7AEF\u521B\u5EFA\u6210\u529F`);
83
+ logger.info(`\u2601\uFE0F [AliyunOSSProvider] \u6D4B\u8BD5\u8FDE\u63A5... testConnection`);
56
84
  await this.testConnection();
57
85
  this.isInitialized = true;
58
86
  logger.info(`\u2705 [AliyunOSSProvider] \u963F\u91CC\u4E91OSS${configChanged ? "\u91CD\u65B0" : ""}\u521D\u59CB\u5316\u5B8C\u6210`);
@@ -345,18 +373,28 @@ var AliyunOSSProvider = class {
345
373
  });
346
374
  logger.info(`\u2705 [AliyunOSSProvider] OSS\u8FDE\u63A5\u6D4B\u8BD5\u6210\u529F`);
347
375
  } catch (error) {
348
- if (this.isOSSError(error)) {
349
- if (error.code === "NoSuchBucket") {
376
+ logger.error("\u274C [AliyunOSSProvider] OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25\uFF0C\u539F\u59CB\u9519\u8BEF:", error);
377
+ let errorCode;
378
+ let errorMessage = "\u672A\u77E5\u9519\u8BEF";
379
+ try {
380
+ errorCode = error?.code;
381
+ errorMessage = error?.message || "\u672A\u77E5\u9519\u8BEF";
382
+ } catch (accessError) {
383
+ logger.warn("\u65E0\u6CD5\u8BBF\u95EE\u9519\u8BEF\u5BF9\u8C61\u7684\u5C5E\u6027:", accessError);
384
+ errorMessage = "\u65E0\u6CD5\u89E3\u6790\u9519\u8BEF\u4FE1\u606F";
385
+ }
386
+ if (typeof errorCode === "string") {
387
+ if (errorCode === "NoSuchBucket") {
350
388
  throw new StorageProviderError(`\u5B58\u50A8\u6876\u4E0D\u5B58\u5728: ${this.config.bucket}`);
351
- }
352
- if (error.code === "InvalidAccessKeyId") {
389
+ } else if (errorCode === "InvalidAccessKeyId") {
353
390
  throw new StorageProviderError("Access Key ID \u65E0\u6548");
354
- }
355
- if (error.code === "SignatureDoesNotMatch") {
391
+ } else if (errorCode === "SignatureDoesNotMatch") {
356
392
  throw new StorageProviderError("Access Key Secret \u65E0\u6548");
393
+ } else {
394
+ throw new StorageProviderError(`OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25: ${errorCode} - ${errorMessage}`);
357
395
  }
358
396
  }
359
- throw error;
397
+ throw new StorageProviderError(`OSS\u8FDE\u63A5\u6D4B\u8BD5\u5931\u8D25: ${errorMessage}`);
360
398
  }
361
399
  }
362
400
  /**
@@ -409,16 +447,26 @@ var AliyunOSSProvider = class {
409
447
  * 判断是否为OSS错误
410
448
  */
411
449
  isOSSError(error) {
412
- return error && typeof error.code === "string" && typeof error.name === "string";
450
+ if (!error || typeof error !== "object") {
451
+ return false;
452
+ }
453
+ return typeof error.code === "string" && typeof (error.name || "") === "string" && typeof (error.message || "") === "string";
413
454
  }
414
455
  /**
415
456
  * 格式化OSS错误信息
416
457
  */
417
458
  formatOSSError(error) {
418
459
  if (this.isOSSError(error)) {
419
- return `${error.code}: ${error.message}${error.requestId ? ` (RequestId: ${error.requestId})` : ""}`;
460
+ const requestId = error.requestId ? ` (RequestId: ${error.requestId})` : "";
461
+ return `${error.code}: ${error.message}${requestId}`;
462
+ }
463
+ if (error instanceof Error) {
464
+ return error.message;
465
+ }
466
+ if (typeof error === "string") {
467
+ return error;
420
468
  }
421
- return error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF";
469
+ return "\u672A\u77E5\u9519\u8BEF";
422
470
  }
423
471
  /**
424
472
  * 流式上传(可选实现)
@@ -530,5 +578,5 @@ var AliyunOSSProvider = class {
530
578
  };
531
579
 
532
580
  export { AliyunOSSProvider };
533
- //# sourceMappingURL=chunk-OHUE7EL6.mjs.map
534
- //# sourceMappingURL=chunk-OHUE7EL6.mjs.map
581
+ //# sourceMappingURL=chunk-SWWRT5FN.mjs.map
582
+ //# sourceMappingURL=chunk-SWWRT5FN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/universalFile/server/providers/AliyunOSSProvider.ts"],"names":[],"mappings":"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","file":"chunk-SWWRT5FN.mjs","sourcesContent":["/**\n * 阿里云OSS存储提供者实现\n */\n\nimport OSS from 'ali-oss';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IStorageProvider,\n StorageConfig,\n AliyunOSSConfig,\n StorageResult,\n UploadFileInfo,\n StorageType,\n} from '../types';\n\nimport { StorageProviderError } from '../types';\n\nconst logger = createLogger('AliyunOSSProvider');\n\n/**\n * 阿里云OSS存储提供者\n */\nexport class AliyunOSSProvider implements IStorageProvider {\n readonly type: StorageType = 'aliyun-oss';\n\n private config: AliyunOSSConfig | null = null;\n private client: any = null;\n private isInitialized = false;\n\n /**\n * 初始化存储提供者\n */\n async initialize(config: StorageConfig): Promise<void> {\n return this.reinitialize(config);\n }\n\n /**\n * 重新初始化存储提供者(支持配置热更新)\n */\n async reinitialize(config: StorageConfig): Promise<void> {\n if (config.type !== 'aliyun-oss') {\n throw new StorageProviderError('配置类型不匹配:期望 aliyun-oss');\n }\n\n const newConfig = config as AliyunOSSConfig;\n\n // 检查配置是否发生变化\n const configChanged =\n !this.config ||\n this.config.region !== newConfig.region ||\n this.config.bucket !== newConfig.bucket ||\n this.config.accessKeyId !== newConfig.accessKeyId ||\n this.config.accessKeySecret !== newConfig.accessKeySecret ||\n this.config.customDomain !== newConfig.customDomain ||\n this.config.secure !== newConfig.secure ||\n this.config.internal !== newConfig.internal;\n\n if (configChanged) {\n logger.info('🔄 [AliyunOSSProvider] 检测到配置变化,重新初始化OSS客户端');\n logger.info(\n `☁️ [AliyunOSSProvider] 新配置: bucket=${newConfig.bucket}, region=${newConfig.region}`\n );\n } else if (this.isInitialized) {\n logger.info('ℹ️ [AliyunOSSProvider] 配置未变化,跳过重新初始化');\n return;\n }\n\n this.config = newConfig;\n\n logger.info(`☁️ [AliyunOSSProvider] ${this.isInitialized ? '重新' : ''}初始化阿里云OSS`);\n logger.info(`☁️ [AliyunOSSProvider] ${this.config ? JSON.stringify(this.config) : ''}`);\n\n try {\n // 验证必需的配置项\n this.validateConfig();\n\n // 确保配置值是有效的字符串\n if (!this.config.region || typeof this.config.region !== 'string') {\n throw new Error('OSS region 必须是有效的字符串');\n }\n if (!this.config.bucket || typeof this.config.bucket !== 'string') {\n throw new Error('OSS bucket 必须是有效的字符串');\n }\n if (!this.config.accessKeyId || typeof this.config.accessKeyId !== 'string') {\n throw new Error('OSS accessKeyId 必须是有效的字符串');\n }\n if (!this.config.accessKeySecret || typeof this.config.accessKeySecret !== 'string') {\n throw new Error('OSS accessKeySecret 必须是有效的字符串');\n }\n\n logger.info(`☁️ [AliyunOSSProvider] 创建OSS客户端配置:`, {\n region: this.config.region,\n bucket: this.config.bucket,\n hasAccessKeyId: !!this.config.accessKeyId,\n hasAccessKeySecret: !!this.config.accessKeySecret,\n secure: this.config.secure !== false,\n internal: this.config.internal || false,\n cname: !!this.config.customDomain,\n endpoint: this.config.customDomain || '默认端点',\n });\n\n // 创建OSS客户端\n this.client = new OSS({\n region: this.config.region,\n bucket: this.config.bucket,\n accessKeyId: this.config.accessKeyId,\n accessKeySecret: this.config.accessKeySecret,\n secure: this.config.secure !== false, // 默认使用HTTPS\n internal: this.config.internal || false, // 默认使用公网\n timeout: 300000, // 5分钟超时\n cname: !!this.config.customDomain, // 是否使用自定义域名\n endpoint: this.config.customDomain || undefined,\n });\n\n if (!this.client) {\n throw new Error('OSS客户端创建失败');\n }\n\n logger.info(`☁️ [AliyunOSSProvider] OSS客户端创建成功`);\n logger.info(`☁️ [AliyunOSSProvider] 测试连接... testConnection`);\n\n // 测试连接\n await this.testConnection();\n\n this.isInitialized = true;\n logger.info(`✅ [AliyunOSSProvider] 阿里云OSS${configChanged ? '重新' : ''}初始化完成`);\n } catch (error) {\n logger.error('❌ [AliyunOSSProvider] 阿里云OSS初始化失败:', error);\n throw new StorageProviderError(\n `阿里云OSS初始化失败: ${error instanceof Error ? error.message : '未知错误'}`\n );\n }\n }\n\n /**\n * 上传文件\n */\n async upload(fileInfo: UploadFileInfo, filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [AliyunOSSProvider] 开始上传文件到OSS: ${filePath}`);\n\n try {\n // 将File对象转换为Buffer\n const buffer = Buffer.from(await fileInfo.file.arrayBuffer());\n\n // 构建上传选项\n const options: any = {\n headers: {\n 'Content-Type': fileInfo.file.type || 'application/octet-stream',\n 'Content-Length': fileInfo.file.size.toString(),\n },\n meta: {\n uid: 0, // 必需字段\n pid: 0, // 必需字段\n originalName: encodeURIComponent(fileInfo.file.name),\n moduleId: fileInfo.moduleId,\n businessId: fileInfo.businessId || '',\n uploadTime: new Date().toISOString(),\n // 对元数据进行编码处理,避免中文字符问题\n ...this.encodeMetadata(fileInfo.metadata || {}),\n },\n };\n\n // 根据文件大小选择上传方式\n let result: any;\n\n if (fileInfo.file.size > 100 * 1024 * 1024) {\n // 大于100MB使用分片上传\n logger.info(\n `📦 [AliyunOSSProvider] 使用分片上传大文件: ${filePath}, 大小: ${fileInfo.file.size}`\n );\n result = await this.multipartUpload(filePath, buffer, options);\n } else {\n logger.info(\n `📤 [AliyunOSSProvider] 使用普通上传: ${filePath}, 大小: ${fileInfo.file.size}`\n );\n result = await this.client.put(filePath, buffer, options);\n }\n\n // 生成访问URL\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(`✅ [AliyunOSSProvider] 文件上传完成: ${filePath}, 耗时: ${uploadTime}ms`);\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: fileInfo.file.size,\n data: {\n etag: result.data ? JSON.stringify(result.data) : '',\n requestId: result.res?.rt || 0,\n uploadTime,\n ossUrl: result.url || result.name,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 下载文件\n */\n async download(filePath: string): Promise<Buffer> {\n this.ensureInitialized();\n\n logger.info(`📥 [AliyunOSSProvider] 开始从OSS下载文件: ${filePath}`);\n\n try {\n const result = await this.client.get(filePath);\n\n if (!result.content || !Buffer.isBuffer(result.content)) {\n throw new StorageProviderError('下载的文件内容格式错误');\n }\n\n logger.info(\n `✅ [AliyunOSSProvider] 文件下载完成: ${filePath}, 大小: ${result.content.length}`\n );\n\n return result.content;\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件下载失败: ${filePath}:`, error);\n\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n throw new StorageProviderError(`文件不存在: ${filePath}`);\n }\n\n throw new StorageProviderError(`文件下载失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 删除文件\n */\n async delete(filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`🗑️ [AliyunOSSProvider] 开始从OSS删除文件: ${filePath}`);\n\n try {\n const result = await this.client.delete(filePath);\n\n logger.info(`✅ [AliyunOSSProvider] 文件删除完成: ${filePath}`);\n\n return {\n success: true,\n data: {\n requestId: result.res?.rt || 0,\n deletedPath: filePath,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件删除失败: ${filePath}:`, error);\n\n // OSS中删除不存在的文件不会报错,但我们统一处理\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n logger.warn(`⚠️ [AliyunOSSProvider] 文件不存在: ${filePath}`);\n return {\n success: true,\n data: { reason: 'file_not_exists' },\n };\n }\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 获取文件信息\n */\n async getFileInfo(filePath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n try {\n const result = await this.client.head(filePath);\n\n return {\n success: true,\n size: parseInt(String(result.meta['content-length'] || '0')),\n data: {\n etag: result.meta.etag || '',\n lastModified: result.meta['last-modified'] || '',\n contentType: result.meta['content-type'],\n meta: result.meta,\n size: parseInt(String(result.meta['content-length'] || '0')),\n },\n };\n } catch (error) {\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n return {\n success: false,\n error: '文件不存在',\n };\n }\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 生成访问URL\n */\n async getAccessUrl(filePath: string, expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n try {\n // 对于图片文件,直接返回公开URL,避免CORS问题\n // 对于其他文件,使用签名URL\n const isImage = /\\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)$/i.test(filePath);\n\n if (isImage) {\n // 图片文件使用公开URL\n return this.generateAccessUrl(filePath);\n } else {\n // 其他文件使用签名URL\n const expires = expiresIn || 3600; // 默认1小时\n const signedUrl = this.client.signatureUrl(filePath, {\n expires,\n method: 'GET',\n });\n\n return signedUrl;\n }\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 生成访问URL失败: ${filePath}:`, error);\n throw new StorageProviderError(`生成访问URL失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 生成预签名上传URL\n */\n async getUploadUrl(filePath: string, expiresIn?: number): Promise<string> {\n this.ensureInitialized();\n\n try {\n const expires = expiresIn || 3600; // 默认1小时\n const signedUrl = this.client.signatureUrl(filePath, {\n expires,\n method: 'PUT',\n });\n\n return signedUrl;\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 生成上传URL失败: ${filePath}:`, error);\n throw new StorageProviderError(`生成上传URL失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 检查文件是否存在\n */\n async exists(filePath: string): Promise<boolean> {\n this.ensureInitialized();\n\n try {\n await this.client.head(filePath);\n return true;\n } catch (error) {\n if (this.isOSSError(error) && error.code === 'NoSuchKey') {\n return false;\n }\n // 其他错误也视为文件不存在\n logger.warn(`⚠️ [AliyunOSSProvider] 检查文件存在性时出错: ${filePath}:`, error);\n return false;\n }\n }\n\n /**\n * 列出文件(详细信息)\n */\n async listFiles(prefix: string, delimiter: string = '/', maxKeys: number = 1000): Promise<{\n files: Array<{\n name: string;\n url: string;\n size: number;\n lastModified: string;\n etag: string;\n type: string;\n }>;\n folders: string[];\n nextMarker?: string;\n }> {\n this.ensureInitialized();\n\n try {\n const options: any = {\n prefix,\n delimiter,\n 'max-keys': String(maxKeys),\n };\n\n const result = await this.client.list(options);\n\n const files = (result.objects || []).map((obj: any) => ({\n name: obj.name,\n url: this.generateAccessUrl(obj.name),\n size: obj.size,\n lastModified: obj.lastModified,\n etag: obj.etag,\n type: 'file',\n }));\n\n const folders = result.prefixes || [];\n\n return {\n files,\n folders,\n nextMarker: result.nextMarker,\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 列出文件失败: ${prefix}:`, error);\n throw new StorageProviderError(`列出文件失败: ${this.formatOSSError(error)}`);\n }\n }\n\n /**\n * 列出文件\n */\n async list(prefix: string, maxKeys?: number): Promise<string[]> {\n this.ensureInitialized();\n\n try {\n const options: any = {\n prefix,\n 'max-keys': String(maxKeys || 1000),\n };\n\n const result = await this.client.list(options);\n\n return result.objects?.map((obj: any) => obj.name) || [];\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 列出文件失败: ${prefix}:`, error);\n return [];\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.client || !this.config) {\n throw new StorageProviderError('OSS存储提供者未初始化');\n }\n }\n\n /**\n * 验证配置\n */\n private validateConfig(): void {\n if (!this.config) {\n throw new StorageProviderError('OSS配置为空');\n }\n\n const required = ['region', 'bucket', 'accessKeyId', 'accessKeySecret'];\n const missing = required.filter((key) => !this.config![key as keyof AliyunOSSConfig]);\n\n if (missing.length > 0) {\n throw new StorageProviderError(`OSS配置缺少必需项: ${missing.join(', ')}`);\n }\n }\n\n /**\n * 测试连接\n */\n private async testConnection(): Promise<void> {\n try {\n // 尝试列出少量对象来测试连接\n await this.client.list({\n 'max-keys': '1',\n });\n logger.info(`✅ [AliyunOSSProvider] OSS连接测试成功`);\n } catch (error: any) {\n logger.error('❌ [AliyunOSSProvider] OSS连接测试失败,原始错误:', error);\n\n // 安全地检查错误类型,避免生产环境中的压缩问题\n let errorCode: string | undefined;\n let errorMessage: string = '未知错误';\n\n try {\n errorCode = error?.code;\n errorMessage = error?.message || '未知错误';\n } catch (accessError) {\n // 如果访问错误属性失败,使用通用错误信息\n logger.warn('无法访问错误对象的属性:', accessError);\n errorMessage = '无法解析错误信息';\n }\n\n if (typeof errorCode === 'string') {\n if (errorCode === 'NoSuchBucket') {\n throw new StorageProviderError(`存储桶不存在: ${this.config!.bucket}`);\n }\n else if (errorCode === 'InvalidAccessKeyId') {\n throw new StorageProviderError('Access Key ID 无效');\n }\n else if (errorCode === 'SignatureDoesNotMatch') {\n throw new StorageProviderError('Access Key Secret 无效');\n }\n else {\n throw new StorageProviderError(`OSS连接测试失败: ${errorCode} - ${errorMessage}`);\n }\n }\n\n // 如果不是标准的OSS错误,抛出通用错误\n throw new StorageProviderError(`OSS连接测试失败: ${errorMessage}`);\n }\n }\n\n /**\n * 分片上传大文件\n */\n private async multipartUpload(filePath: string, buffer: Buffer, options: any): Promise<any> {\n logger.info(`📦 [AliyunOSSProvider] 使用多分片上传`);\n\n // 使用OSS的multipartUpload方法\n const result = await this.client.multipartUpload(filePath, buffer, {\n partSize: 10 * 1024 * 1024, // 10MB per chunk\n parallel: 4, // 并发数\n progress: (p: number) => {\n if (p % 0.1 < 0.01) {\n // 每10%显示一次进度\n logger.info(`📦 [AliyunOSSProvider] 上传进度: ${(p * 100).toFixed(1)}%`);\n }\n },\n meta: options.meta,\n headers: options.headers,\n });\n\n return {\n name: result.name,\n url: result.name, // OSS返回的是object名称\n data: result.data,\n res: result.res,\n };\n }\n\n /**\n * 生成公开访问URL\n */\n private generateAccessUrl(filePath: string): string {\n if (!this.config) {\n throw new StorageProviderError('OSS配置为空');\n }\n\n // 确保文件路径不以斜杠开头\n const normalizedPath = filePath.startsWith('/') ? filePath.substring(1) : filePath;\n\n if (this.config.customDomain) {\n // 使用自定义域名\n const protocol = this.config.secure !== false ? 'https' : 'http';\n const url = `${protocol}://${this.config.customDomain}/${normalizedPath}`;\n logger.info(`🔗 [AliyunOSSProvider] 使用自定义域名: ${url}`);\n return url;\n } else {\n // 使用默认OSS域名\n const protocol = this.config.secure !== false ? 'https' : 'http';\n const url = `${protocol}://${this.config.bucket}.${this.config.region}.aliyuncs.com/${normalizedPath}`;\n logger.info(`🔗 [AliyunOSSProvider] 使用默认OSS域名: ${url}`);\n return url;\n }\n }\n\n /**\n * 判断是否为OSS错误\n */\n private isOSSError(\n error: any\n ): error is { code: string; name: string; message: string; requestId?: string } {\n // 安全地检查错误属性,避免生产环境中的压缩问题\n if (!error || typeof error !== 'object') {\n return false;\n }\n\n return typeof error.code === 'string' &&\n typeof (error.name || '') === 'string' &&\n typeof (error.message || '') === 'string';\n }\n\n /**\n * 格式化OSS错误信息\n */\n private formatOSSError(error: any): string {\n if (this.isOSSError(error)) {\n const requestId = error.requestId ? ` (RequestId: ${error.requestId})` : '';\n return `${error.code}: ${error.message}${requestId}`;\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return '未知错误';\n }\n\n /**\n * 流式上传(可选实现)\n */\n async uploadStream(\n readableStream: NodeJS.ReadableStream,\n filePath: string,\n contentType?: string,\n contentLength?: number\n ): Promise<StorageResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info(`📤 [AliyunOSSProvider] 开始流式上传文件到OSS: ${filePath}`);\n\n try {\n const options: any = {\n timeout: 300000,\n mime: contentType || 'application/octet-stream',\n meta: { uid: 0, pid: 0 },\n callback: { url: '', body: '' },\n headers: {} as any,\n };\n\n if (contentLength) {\n options.headers['Content-Length'] = contentLength.toString();\n }\n\n const result = await this.client.putStream(filePath, readableStream, options);\n\n const accessUrl = this.generateAccessUrl(filePath);\n\n const uploadTime = Date.now() - startTime;\n logger.info(`✅ [AliyunOSSProvider] 流式上传完成: ${filePath}, 耗时: ${uploadTime}ms`);\n\n return {\n success: true,\n path: filePath,\n url: accessUrl,\n size: contentLength,\n data: {\n name: result.name,\n requestId: result.res?.rt || 0,\n uploadTime,\n ossUrl: result.url || result.name,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 流式上传失败: ${filePath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 批量删除文件\n */\n async batchDelete(filePaths: string[]): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`🗑️ [AliyunOSSProvider] 开始批量删除文件,数量: ${filePaths.length}`);\n\n try {\n const result = await this.client.deleteMulti(filePaths, {\n quiet: false, // 返回删除结果\n });\n\n logger.info(`✅ [AliyunOSSProvider] 批量删除完成,成功: ${result.deleted?.length || 0}`);\n\n return {\n success: true,\n data: {\n deleted: result.deleted,\n requestId: result.res?.rt || 0,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 批量删除失败:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 复制文件\n */\n async copy(sourcePath: string, targetPath: string): Promise<StorageResult> {\n this.ensureInitialized();\n\n logger.info(`📋 [AliyunOSSProvider] 开始复制文件: ${sourcePath} -> ${targetPath}`);\n\n try {\n const result = await this.client.copy(targetPath, sourcePath);\n\n logger.info(`✅ [AliyunOSSProvider] 文件复制完成: ${sourcePath} -> ${targetPath}`);\n\n return {\n success: true,\n data: {\n etag: result.data?.etag,\n lastModified: result.data?.lastModified,\n requestId: result.res?.rt || 0,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunOSSProvider] 文件复制失败: ${sourcePath} -> ${targetPath}:`, error);\n\n return {\n success: false,\n error: this.formatOSSError(error),\n };\n }\n }\n\n /**\n * 编码元数据,避免中文字符在HTTP头部中的问题\n */\n private encodeMetadata(metadata: Record<string, any>): Record<string, string> {\n const encoded: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== null && value !== undefined) {\n // 将值转换为字符串并进行URL编码\n const stringValue = String(value);\n encoded[key] = encodeURIComponent(stringValue);\n }\n }\n\n return encoded;\n }\n}\n\n"]}
@@ -1,6 +1,6 @@
1
1
  export { M as MmdPlaylist, f as MmdPlaylistNode, j as MmdPresetItem, h as MmdResourceOption, N as NewMmdPlaylist, g as NewMmdPlaylistNode, k as NewMmdPresetItem, i as NewMmdResourceOption, a as mmdPlaylistNodes, e as mmdPlaylistNodesRelations, m as mmdPlaylists, d as mmdPlaylistsRelations, c as mmdPresetItems, b as mmdResourceOptions } from '../../drizzle-schema-BNhqj2AZ.mjs';
2
2
  import { M as MMDPlaylistConfig } from '../../types-HorDyIRv.mjs';
3
- import { U as UniversalFileService } from '../../UniversalFileService-CGGzYeeF.mjs';
3
+ import { U as UniversalFileService } from '../../UniversalFileService-ChicEKg7.mjs';
4
4
  import { F as FileMetadata } from '../../types-CK4We_aI.mjs';
5
5
  import 'drizzle-orm';
6
6
  import 'drizzle-orm/pg-core';
@@ -1,6 +1,6 @@
1
1
  export { M as MmdPlaylist, f as MmdPlaylistNode, j as MmdPresetItem, h as MmdResourceOption, N as NewMmdPlaylist, g as NewMmdPlaylistNode, k as NewMmdPresetItem, i as NewMmdResourceOption, a as mmdPlaylistNodes, e as mmdPlaylistNodesRelations, m as mmdPlaylists, d as mmdPlaylistsRelations, c as mmdPresetItems, b as mmdResourceOptions } from '../../drizzle-schema-BNhqj2AZ.js';
2
2
  import { M as MMDPlaylistConfig } from '../../types-HorDyIRv.js';
3
- import { U as UniversalFileService } from '../../UniversalFileService-BuHN-jrR.js';
3
+ import { U as UniversalFileService } from '../../UniversalFileService-Ct4baUMz.js';
4
4
  import { F as FileMetadata } from '../../types-CK4We_aI.js';
5
5
  import 'drizzle-orm';
6
6
  import 'drizzle-orm/pg-core';
@@ -1,7 +1,7 @@
1
1
  import { a as UploadFileInfo, c as UploadProgress, F as FileMetadata, d as FileQueryOptions, e as PaginatedResult, B as BatchOperationResult, b as ProcessingOptions } from '../types-CK4We_aI.mjs';
2
2
  export { A as AccessPermission, l as AudioProcessingOptions, k as CDNProviderError, C as CDNType, o as FileEvent, f as FileEventListener, n as FileEventType, i as FileProcessingError, g as FileServiceError, h as FileUploadError, I as ImageProcessingOptions, P as ProcessorType, j as StorageProviderError, S as StorageType, m as UploadResult, U as UploadStatus, V as VideoProcessingOptions } from '../types-CK4We_aI.mjs';
3
3
  import React__default from 'react';
4
- import { U as UniversalFileService } from '../UniversalFileService-CGGzYeeF.mjs';
4
+ import { U as UniversalFileService } from '../UniversalFileService-ChicEKg7.mjs';
5
5
  import 'events';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import { a as UploadFileInfo, c as UploadProgress, F as FileMetadata, d as FileQueryOptions, e as PaginatedResult, B as BatchOperationResult, b as ProcessingOptions } from '../types-CK4We_aI.js';
2
2
  export { A as AccessPermission, l as AudioProcessingOptions, k as CDNProviderError, C as CDNType, o as FileEvent, f as FileEventListener, n as FileEventType, i as FileProcessingError, g as FileServiceError, h as FileUploadError, I as ImageProcessingOptions, P as ProcessorType, j as StorageProviderError, S as StorageType, m as UploadResult, U as UploadStatus, V as VideoProcessingOptions } from '../types-CK4We_aI.js';
3
3
  import React__default from 'react';
4
- import { U as UniversalFileService } from '../UniversalFileService-BuHN-jrR.js';
4
+ import { U as UniversalFileService } from '../UniversalFileService-Ct4baUMz.js';
5
5
  import 'events';
6
6
 
7
7
  /**
@@ -1,5 +1,5 @@
1
- import { a as UniversalFileServiceConfig, S as StorageConfig, I as IStorageProvider, b as StorageType, c as UploadFileInfo, d as StorageResult, e as ICDNProvider, C as CDNType, f as CDNConfig, g as CDNResult, h as IFileProcessor, P as ProcessorType, i as ProcessingOptions, j as ProcessingResult, k as IFileMetadataRepository, A as AliyunOSSConfig, l as AliyunCDNConfig, L as LocalStorageConfig, U as UniversalFileService } from '../../UniversalFileService-CGGzYeeF.mjs';
2
- export { B as CDNProviderError, o as CDNStats, m as CacheConfig, t as FileEvent, u as FileEventListener, v as FileEventType, y as FileProcessingError, r as FileQueryOptions, q as FileRecord, w as FileServiceError, F as FileServicePersistenceConfig, x as FileUploadError, s as PaginatedResult, p as ProcessorInfo, n as StorageMetadata, z as StorageProviderError } from '../../UniversalFileService-CGGzYeeF.mjs';
1
+ import { a as UniversalFileServiceConfig, S as StorageConfig, I as IStorageProvider, b as StorageType, c as UploadFileInfo, d as StorageResult, e as ICDNProvider, C as CDNType, f as CDNConfig, g as CDNResult, h as IFileProcessor, P as ProcessorType, i as ProcessingOptions, j as ProcessingResult, k as IFileMetadataRepository, A as AliyunOSSConfig, l as AliyunCDNConfig, L as LocalStorageConfig, U as UniversalFileService } from '../../UniversalFileService-ChicEKg7.mjs';
2
+ export { B as CDNProviderError, o as CDNStats, m as CacheConfig, t as FileEvent, u as FileEventListener, v as FileEventType, y as FileProcessingError, r as FileQueryOptions, q as FileRecord, w as FileServiceError, F as FileServicePersistenceConfig, x as FileUploadError, s as PaginatedResult, p as ProcessorInfo, n as StorageMetadata, z as StorageProviderError } from '../../UniversalFileService-ChicEKg7.mjs';
3
3
  import { I as ImageProcessingOptions, l as AudioProcessingOptions, V as VideoProcessingOptions } from '../../types-CK4We_aI.mjs';
4
4
  import { EventEmitter } from 'events';
5
5
  import { NextResponse } from 'next/server';
@@ -1,5 +1,5 @@
1
- import { a as UniversalFileServiceConfig, S as StorageConfig, I as IStorageProvider, b as StorageType, c as UploadFileInfo, d as StorageResult, e as ICDNProvider, C as CDNType, f as CDNConfig, g as CDNResult, h as IFileProcessor, P as ProcessorType, i as ProcessingOptions, j as ProcessingResult, k as IFileMetadataRepository, A as AliyunOSSConfig, l as AliyunCDNConfig, L as LocalStorageConfig, U as UniversalFileService } from '../../UniversalFileService-BuHN-jrR.js';
2
- export { B as CDNProviderError, o as CDNStats, m as CacheConfig, t as FileEvent, u as FileEventListener, v as FileEventType, y as FileProcessingError, r as FileQueryOptions, q as FileRecord, w as FileServiceError, F as FileServicePersistenceConfig, x as FileUploadError, s as PaginatedResult, p as ProcessorInfo, n as StorageMetadata, z as StorageProviderError } from '../../UniversalFileService-BuHN-jrR.js';
1
+ import { a as UniversalFileServiceConfig, S as StorageConfig, I as IStorageProvider, b as StorageType, c as UploadFileInfo, d as StorageResult, e as ICDNProvider, C as CDNType, f as CDNConfig, g as CDNResult, h as IFileProcessor, P as ProcessorType, i as ProcessingOptions, j as ProcessingResult, k as IFileMetadataRepository, A as AliyunOSSConfig, l as AliyunCDNConfig, L as LocalStorageConfig, U as UniversalFileService } from '../../UniversalFileService-Ct4baUMz.js';
2
+ export { B as CDNProviderError, o as CDNStats, m as CacheConfig, t as FileEvent, u as FileEventListener, v as FileEventType, y as FileProcessingError, r as FileQueryOptions, q as FileRecord, w as FileServiceError, F as FileServicePersistenceConfig, x as FileUploadError, s as PaginatedResult, p as ProcessorInfo, n as StorageMetadata, z as StorageProviderError } from '../../UniversalFileService-Ct4baUMz.js';
3
3
  import { I as ImageProcessingOptions, l as AudioProcessingOptions, V as VideoProcessingOptions } from '../../types-CK4We_aI.js';
4
4
  import { EventEmitter } from 'events';
5
5
  import { NextResponse } from 'next/server';