sa2kit 1.0.0 → 1.0.2

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.
Files changed (99) hide show
  1. package/dist/UniversalFileService-CEZRJ87g.d.mts +727 -0
  2. package/dist/UniversalFileService-CEZRJ87g.d.ts +727 -0
  3. package/dist/api/index.d.mts +248 -0
  4. package/dist/api/index.d.ts +248 -0
  5. package/dist/api/index.js +294 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/index.mjs +290 -0
  8. package/dist/api/index.mjs.map +1 -0
  9. package/dist/auth/client/index.d.mts +52 -3
  10. package/dist/auth/client/index.d.ts +52 -3
  11. package/dist/auth/components/index.d.mts +149 -4
  12. package/dist/auth/components/index.d.ts +149 -4
  13. package/dist/auth/components/index.js +243 -9
  14. package/dist/auth/components/index.js.map +1 -1
  15. package/dist/auth/components/index.mjs +237 -4
  16. package/dist/auth/components/index.mjs.map +1 -1
  17. package/dist/auth/hooks/index.d.mts +31 -2
  18. package/dist/auth/hooks/index.d.ts +31 -2
  19. package/dist/auth/index.d.mts +5 -5
  20. package/dist/auth/index.d.ts +5 -5
  21. package/dist/auth/index.js +49 -17
  22. package/dist/auth/index.mjs +1 -1
  23. package/dist/auth/routes/index.d.mts +103 -5
  24. package/dist/auth/routes/index.d.ts +103 -5
  25. package/dist/auth/routes/index.js +37 -5
  26. package/dist/auth/routes/index.mjs +1 -1
  27. package/dist/chunk-42IJ7HEI.js +573 -0
  28. package/dist/chunk-42IJ7HEI.js.map +1 -0
  29. package/dist/chunk-7XLFSPDG.mjs +31 -0
  30. package/dist/chunk-7XLFSPDG.mjs.map +1 -0
  31. package/dist/chunk-GCVOKQZP.js +36 -0
  32. package/dist/chunk-GCVOKQZP.js.map +1 -0
  33. package/dist/chunk-IBLB7ARJ.mjs +560 -0
  34. package/dist/chunk-IBLB7ARJ.mjs.map +1 -0
  35. package/dist/{chunk-6FNUWAIV.js → chunk-LX4XX6W7.js} +54 -8
  36. package/dist/chunk-LX4XX6W7.js.map +1 -0
  37. package/dist/{chunk-HXFFYNIF.mjs → chunk-T5OZHYVM.mjs} +54 -8
  38. package/dist/chunk-T5OZHYVM.mjs.map +1 -0
  39. package/dist/config/server/index.d.mts +1533 -0
  40. package/dist/config/server/index.d.ts +1533 -0
  41. package/dist/config/server/index.js +1177 -0
  42. package/dist/config/server/index.js.map +1 -0
  43. package/dist/config/server/index.mjs +1138 -0
  44. package/dist/config/server/index.mjs.map +1 -0
  45. package/dist/i18n/index.d.mts +2 -1
  46. package/dist/i18n/index.d.ts +2 -1
  47. package/dist/i18n/index.js +125 -61
  48. package/dist/i18n/index.js.map +1 -1
  49. package/dist/i18n/index.mjs +126 -62
  50. package/dist/i18n/index.mjs.map +1 -1
  51. package/dist/index.js +6 -6
  52. package/dist/index.mjs +1 -1
  53. package/dist/mmd/index.d.mts +346 -0
  54. package/dist/mmd/index.d.ts +346 -0
  55. package/dist/mmd/index.js +1535 -0
  56. package/dist/mmd/index.js.map +1 -0
  57. package/dist/mmd/index.mjs +1503 -0
  58. package/dist/mmd/index.mjs.map +1 -0
  59. package/dist/storage/index.d.mts +1 -0
  60. package/dist/storage/index.d.ts +1 -0
  61. package/dist/storage/index.js +9 -9
  62. package/dist/storage/index.mjs +1 -1
  63. package/dist/{index-8VoHap_4.d.mts → types-CroexXnI.d.ts} +38 -44
  64. package/dist/{index-8VoHap_4.d.ts → types-DmsXCWvm.d.mts} +38 -44
  65. package/dist/{types-DAxQ1MeY.d.ts → types-Dt0oqeFM.d.mts} +1 -1
  66. package/dist/{types-DT8LVCvE.d.mts → types-zK6kDzDQ.d.ts} +1 -1
  67. package/dist/universalExport/index.js +17 -32
  68. package/dist/universalExport/index.js.map +1 -1
  69. package/dist/universalExport/index.mjs +2 -29
  70. package/dist/universalExport/index.mjs.map +1 -1
  71. package/dist/universalExport/server/index.d.mts +849 -8
  72. package/dist/universalExport/server/index.d.ts +849 -8
  73. package/dist/universalExport/server/index.js +1382 -2
  74. package/dist/universalExport/server/index.js.map +1 -1
  75. package/dist/universalExport/server/index.mjs +1355 -3
  76. package/dist/universalExport/server/index.mjs.map +1 -1
  77. package/dist/universalFile/index.d.mts +54 -3
  78. package/dist/universalFile/index.d.ts +54 -3
  79. package/dist/universalFile/index.js +272 -0
  80. package/dist/universalFile/index.js.map +1 -1
  81. package/dist/universalFile/index.mjs +267 -1
  82. package/dist/universalFile/index.mjs.map +1 -1
  83. package/dist/universalFile/server/index.d.mts +2541 -469
  84. package/dist/universalFile/server/index.d.ts +2541 -469
  85. package/dist/universalFile/server/index.js +830 -64
  86. package/dist/universalFile/server/index.js.map +1 -1
  87. package/dist/universalFile/server/index.mjs +803 -66
  88. package/dist/universalFile/server/index.mjs.map +1 -1
  89. package/package.json +47 -23
  90. package/dist/chunk-6FNUWAIV.js.map +0 -1
  91. package/dist/chunk-APY57REU.js +0 -300
  92. package/dist/chunk-APY57REU.js.map +0 -1
  93. package/dist/chunk-C64RY2OW.mjs +0 -295
  94. package/dist/chunk-C64RY2OW.mjs.map +0 -1
  95. package/dist/chunk-HXFFYNIF.mjs.map +0 -1
  96. package/dist/types-CoGG1rNV.d.mts +0 -258
  97. package/dist/types-CoGG1rNV.d.ts +0 -258
  98. package/dist/types-DW9qar-w.d.mts +0 -52
  99. package/dist/types-DW9qar-w.d.ts +0 -52
@@ -11,7 +11,8 @@ import { EventEmitter } from 'events';
11
11
  import { v4 } from 'uuid';
12
12
  import { LRUCache } from 'lru-cache';
13
13
  import { NextResponse } from 'next/server';
14
- import { sql, eq, and, desc } from 'drizzle-orm';
14
+ import { relations, sql, eq, and, desc } from 'drizzle-orm';
15
+ import { pgTable, timestamp, json, bigint, integer, boolean, varchar, serial, index, text, uuid } from 'drizzle-orm/pg-core';
15
16
 
16
17
  // src/universalFile/server/factory.ts
17
18
  function createFileServiceConfig(options) {
@@ -449,10 +450,10 @@ var AliyunCDNProvider = class {
449
450
  return cdnUrl;
450
451
  }
451
452
  const parsedUrl = new URL(cdnUrl);
452
- const timestamp = Math.floor(Date.now() / 1e3) + expiresIn;
453
- const signString = `${parsedUrl.pathname}-${timestamp}-0-0-${authKey}`;
453
+ const timestamp2 = Math.floor(Date.now() / 1e3) + expiresIn;
454
+ const signString = `${parsedUrl.pathname}-${timestamp2}-0-0-${authKey}`;
454
455
  const authValue = createHash("md5").update(signString).digest("hex");
455
- const signedUrl = `${cdnUrl}?auth_key=${timestamp}-0-0-${authValue}`;
456
+ const signedUrl = `${cdnUrl}?auth_key=${timestamp2}-0-0-${authValue}`;
456
457
  logger.info(`\u2705 [AliyunCDNProvider] \u9632\u76D7\u94FE\u7B7E\u540DURL\u751F\u6210\u5B8C\u6210`);
457
458
  return signedUrl;
458
459
  } catch (error) {
@@ -1291,7 +1292,7 @@ var ImageProcessor = class {
1291
1292
  /**
1292
1293
  * 创建文字水印SVG
1293
1294
  */
1294
- createTextWatermarkSvg(text, opacity) {
1295
+ createTextWatermarkSvg(text2, opacity) {
1295
1296
  const fontSize = 24;
1296
1297
  const padding = 10;
1297
1298
  return `
@@ -1307,7 +1308,7 @@ var ImageProcessor = class {
1307
1308
  stroke-width="1"
1308
1309
  stroke-opacity="${opacity * 0.8}"
1309
1310
  >
1310
- ${text}
1311
+ ${text2}
1311
1312
  </text>
1312
1313
  </svg>
1313
1314
  `.trim();
@@ -2994,13 +2995,9 @@ var UniversalFileService = class extends EventEmitter {
2994
2995
  async reinitializeStorageProviders() {
2995
2996
  logger6.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005...");
2996
2997
  try {
2997
- const ossConfig = this.config.storageProviders["aliyun-oss"];
2998
- if (ossConfig && ossConfig.enabled) {
2999
- const ossProvider = this.storageProviders.get("aliyun-oss");
3000
- if (ossProvider && "reinitialize" in ossProvider) {
3001
- logger6.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005...");
3002
- await ossProvider.reinitialize(ossConfig);
3003
- }
2998
+ const ossProvider = this.storageProviders.get("aliyun-oss");
2999
+ if (ossProvider && "reinitialize" in ossProvider) {
3000
+ logger6.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005...");
3004
3001
  }
3005
3002
  logger6.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210");
3006
3003
  } catch (error) {
@@ -3154,68 +3151,54 @@ var UniversalFileService = class extends EventEmitter {
3154
3151
  if (this.storageProviders.size === 0) {
3155
3152
  await this.registerDefaultStorageProviders();
3156
3153
  }
3157
- for (const [type, config] of Object.entries(this.config.storageProviders)) {
3158
- if (config.enabled) {
3159
- const provider = this.storageProviders.get(type);
3160
- if (provider) {
3161
- try {
3162
- await provider.initialize(config);
3163
- logger6.info(`\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: ${type}`);
3164
- } catch (error) {
3165
- console.warn(`\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5931\u8D25: ${type}:`, error);
3154
+ if (this.config.storageProviders) {
3155
+ for (const [type, config] of Object.entries(this.config.storageProviders)) {
3156
+ if (config && config.enabled) {
3157
+ const provider = this.storageProviders.get(type);
3158
+ if (provider) {
3159
+ try {
3160
+ await provider.initialize(config);
3161
+ logger6.info(`\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: ${type}`);
3162
+ } catch (error) {
3163
+ console.warn(`\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5931\u8D25: ${type}:`, error);
3164
+ }
3165
+ } else {
3166
+ console.warn(`\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u6CE8\u518C: ${type}`);
3166
3167
  }
3167
- } else {
3168
- console.warn(`\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u6CE8\u518C: ${type}`);
3169
3168
  }
3170
3169
  }
3171
3170
  }
3172
3171
  }
3173
3172
  async registerDefaultStorageProviders() {
3174
3173
  logger6.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005...");
3175
- const ossConfig = this.config.storageProviders["aliyun-oss"];
3176
- if (ossConfig && ossConfig.enabled) {
3177
- try {
3178
- const { AliyunOSSProvider: AliyunOSSProvider2 } = await import('../../AliyunOSSProvider-GQMSDJGZ.mjs');
3179
- const ossProvider = new AliyunOSSProvider2();
3180
- this.registerStorageProvider(ossProvider);
3181
- logger6.info("\u2705 [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
3182
- } catch (error) {
3183
- console.warn("\u26A0\uFE0F [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u5931\u8D25:", error);
3184
- }
3185
- }
3186
- const localConfig = this.config.storageProviders["local"];
3187
- if (localConfig && localConfig.enabled) {
3188
- try {
3189
- const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-FVLLHBHO.mjs');
3190
- const localProvider = new LocalStorageProvider2();
3191
- this.registerStorageProvider(localProvider);
3192
- logger6.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
3193
- } catch (error) {
3194
- console.warn("\u26A0\uFE0F [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u5931\u8D25:", error);
3174
+ try {
3175
+ if (this.config.storage) {
3176
+ if (this.config.storage.type === "aliyun-oss" && this.config.storage.enabled) {
3177
+ const { AliyunOSSProvider: AliyunOSSProvider2 } = await import('../../AliyunOSSProvider-GQMSDJGZ.mjs');
3178
+ const ossProvider = new AliyunOSSProvider2();
3179
+ this.registerStorageProvider(ossProvider);
3180
+ logger6.info("\u2705 [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
3181
+ } else if (this.config.storage.type === "local" && this.config.storage.enabled) {
3182
+ const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-FVLLHBHO.mjs');
3183
+ const localProvider = new LocalStorageProvider2();
3184
+ this.registerStorageProvider(localProvider);
3185
+ logger6.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
3186
+ }
3195
3187
  }
3196
- }
3197
- if (this.storageProviders.size === 0) {
3198
- console.warn("\u26A0\uFE0F [UniversalFileService] \u6CA1\u6709\u53EF\u7528\u7684\u5B58\u50A8\u63D0\u4F9B\u8005\uFF0C\u5C1D\u8BD5\u6CE8\u518C\u672C\u5730\u5B58\u50A8\u4F5C\u4E3A\u5907\u7528");
3199
- try {
3188
+ if (this.storageProviders.size === 0) {
3200
3189
  const { LocalStorageProvider: LocalStorageProvider2 } = await import('../../LocalStorageProvider-FVLLHBHO.mjs');
3201
- const localProvider = new LocalStorageProvider2();
3202
- this.registerStorageProvider(localProvider);
3203
- logger6.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F\uFF08\u5907\u7528\uFF09");
3204
- } catch (error) {
3205
- console.error("\u274C [UniversalFileService] \u65E0\u6CD5\u6CE8\u518C\u4EFB\u4F55\u5B58\u50A8\u63D0\u4F9B\u8005:", error);
3206
- throw new Error("\u65E0\u6CD5\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005");
3190
+ const fallbackProvider = new LocalStorageProvider2();
3191
+ this.registerStorageProvider(fallbackProvider);
3192
+ logger6.info("\u2705 [UniversalFileService] \u5DF2\u6CE8\u518C\u5907\u7528\u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005");
3207
3193
  }
3194
+ } catch (error) {
3195
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005\u5931\u8D25:", error);
3196
+ throw new Error("\u65E0\u6CD5\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005");
3208
3197
  }
3209
3198
  }
3210
3199
  async initializeCDNProviders() {
3211
- for (const [type, config] of Object.entries(this.config.cdnProviders)) {
3212
- if (config.enabled) {
3213
- const provider = this.cdnProviders.get(type);
3214
- if (provider) {
3215
- await provider.initialize(config);
3216
- logger6.info(`\u2705 [UniversalFileService] CDN\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: ${type}`);
3217
- }
3218
- }
3200
+ if (this.config.cdn && this.config.cdn.enabled) {
3201
+ logger6.info(`\u2705 [UniversalFileService] CDN\u914D\u7F6E\u5DF2\u542F\u7528: ${this.config.cdn.type}`);
3219
3202
  }
3220
3203
  }
3221
3204
  async initializeFileProcessors() {
@@ -3225,11 +3208,11 @@ var UniversalFileService = class extends EventEmitter {
3225
3208
  }
3226
3209
  }
3227
3210
  async validateFile(file) {
3228
- if (file.size > this.config.maxFileSize) {
3211
+ if (this.config.maxFileSize && file.size > this.config.maxFileSize) {
3229
3212
  throw new FileUploadError(`\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: ${file.size} > ${this.config.maxFileSize}`);
3230
3213
  }
3231
3214
  const mimeType = file.type || getMimeType(file.name);
3232
- if (this.config.allowedMimeTypes.length > 0 && !this.config.allowedMimeTypes.includes(mimeType)) {
3215
+ if (this.config.allowedMimeTypes && this.config.allowedMimeTypes.length > 0 && !this.config.allowedMimeTypes.includes(mimeType)) {
3233
3216
  throw new FileUploadError(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: ${mimeType}`);
3234
3217
  }
3235
3218
  }
@@ -3251,7 +3234,7 @@ var UniversalFileService = class extends EventEmitter {
3251
3234
  uploaderId: fileInfo.metadata?.uploadedBy || "system",
3252
3235
  moduleId: fileInfo.moduleId,
3253
3236
  businessId: fileInfo.businessId,
3254
- storageProvider: this.config.defaultStorage,
3237
+ storageProvider: this.config.defaultStorage || "local",
3255
3238
  storagePath: "",
3256
3239
  accessCount: 0,
3257
3240
  metadata: fileInfo.metadata || {}
@@ -4513,6 +4496,760 @@ function createDrizzleRepository(config) {
4513
4496
  };
4514
4497
  }
4515
4498
 
4516
- export { AliyunCDNProvider, ApiError, ApiErrorCode, AudioProcessor, CacheManager, CacheStrategyType, CdnCacheStrategy2 as CdnCacheStrategy, ConfigValidationError, ErrorHttpStatusMap, ErrorMessages, ImageProcessor, PerformanceMonitor, ProcessingQueue, UniversalFileService, VideoProcessor, cdnCacheStrategy, createAliyunOSSPreset, createDocumentServicePreset, createDrizzleRepository, createFileServiceConfig, createFileServiceFromEnv, createImageServicePreset, createLocalDevPreset, createSmartPreset, createUniversalFileService, createVideoServicePreset, getMimeType, getRequiredEnvVars, validateEnvironment, validateServiceConfig, validateStorageConfig };
4499
+ // src/universalFile/server/config-helpers.ts
4500
+ var logger9 = createLogger("FileConfigHelpers");
4501
+ var DEFAULT_MAX_FILE_SIZE = 104857600;
4502
+ var DEFAULT_ALLOWED_MIME_TYPES = [
4503
+ // 图片类型
4504
+ "image/jpeg",
4505
+ "image/png",
4506
+ "image/gif",
4507
+ "image/webp",
4508
+ "image/svg+xml",
4509
+ "image/bmp",
4510
+ "image/tiff",
4511
+ // 音频类型
4512
+ "audio/mpeg",
4513
+ "audio/wav",
4514
+ "audio/ogg",
4515
+ "audio/mp4",
4516
+ "audio/aac",
4517
+ "audio/webm",
4518
+ "audio/flac",
4519
+ // 视频类型
4520
+ "video/mp4",
4521
+ "video/avi",
4522
+ "video/mov",
4523
+ "video/webm",
4524
+ "video/mkv",
4525
+ "video/mpeg",
4526
+ "video/quicktime",
4527
+ // 文档类型
4528
+ "application/pdf",
4529
+ "text/plain",
4530
+ "application/json",
4531
+ "application/javascript",
4532
+ "text/css",
4533
+ "text/html",
4534
+ "text/markdown",
4535
+ "application/xml",
4536
+ "text/xml",
4537
+ // Office 文档
4538
+ "application/msword",
4539
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
4540
+ "application/vnd.ms-excel",
4541
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
4542
+ "application/vnd.ms-powerpoint",
4543
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
4544
+ // 压缩文件
4545
+ "application/zip",
4546
+ "application/x-zip-compressed",
4547
+ "application/x-rar-compressed",
4548
+ "application/x-7z-compressed",
4549
+ "application/x-tar",
4550
+ "application/gzip",
4551
+ // 3D模型文件
4552
+ "application/octet-stream",
4553
+ "model/gltf+json",
4554
+ "model/gltf-binary",
4555
+ "model/obj",
4556
+ "model/fbx"
4557
+ ];
4558
+ var DEFAULT_CACHE_CONFIG = {
4559
+ enabled: false,
4560
+ metadataTTL: 3600,
4561
+ // 1小时
4562
+ urlTTL: 1800
4563
+ // 30分钟
4564
+ };
4565
+ var DEFAULT_FILE_SERVICE_CONFIG = {
4566
+ maxFileSize: DEFAULT_MAX_FILE_SIZE,
4567
+ allowedMimeTypes: DEFAULT_ALLOWED_MIME_TYPES,
4568
+ cache: DEFAULT_CACHE_CONFIG,
4569
+ enableMonitoring: false
4570
+ };
4571
+ function loadOSSConfigFromEnv() {
4572
+ const region = process.env.ALIYUN_OSS_REGION;
4573
+ const bucket = process.env.ALIYUN_OSS_BUCKET;
4574
+ const accessKeyId = process.env.ALIYUN_OSS_ACCESS_KEY_ID;
4575
+ const accessKeySecret = process.env.ALIYUN_OSS_ACCESS_KEY_SECRET;
4576
+ if (!region || !bucket || !accessKeyId || !accessKeySecret) {
4577
+ logger9.debug("OSS \u73AF\u5883\u53D8\u91CF\u914D\u7F6E\u4E0D\u5B8C\u6574", {
4578
+ hasRegion: !!region,
4579
+ hasBucket: !!bucket,
4580
+ hasAccessKeyId: !!accessKeyId,
4581
+ hasAccessKeySecret: !!accessKeySecret
4582
+ });
4583
+ return null;
4584
+ }
4585
+ const config = {
4586
+ type: "aliyun-oss",
4587
+ enabled: true,
4588
+ region,
4589
+ bucket,
4590
+ accessKeyId,
4591
+ accessKeySecret,
4592
+ customDomain: process.env.ALIYUN_OSS_CUSTOM_DOMAIN,
4593
+ secure: process.env.ALIYUN_OSS_SECURE === "true",
4594
+ internal: process.env.ALIYUN_OSS_INTERNAL === "true"
4595
+ };
4596
+ logger9.info("\u2705 \u4ECE\u73AF\u5883\u53D8\u91CF\u52A0\u8F7D OSS \u914D\u7F6E\u6210\u529F", {
4597
+ region: config.region,
4598
+ bucket: config.bucket,
4599
+ hasCustomDomain: !!config.customDomain
4600
+ });
4601
+ return config;
4602
+ }
4603
+ function loadCDNConfigFromEnv() {
4604
+ const domain = process.env.ALIYUN_CDN_DOMAIN;
4605
+ const accessKeyId = process.env.ALIYUN_CDN_ACCESS_KEY_ID;
4606
+ const accessKeySecret = process.env.ALIYUN_CDN_ACCESS_KEY_SECRET;
4607
+ if (!domain || !accessKeyId || !accessKeySecret) {
4608
+ logger9.debug("CDN \u73AF\u5883\u53D8\u91CF\u672A\u914D\u7F6E\u6216\u4E0D\u5B8C\u6574");
4609
+ return null;
4610
+ }
4611
+ const config = {
4612
+ type: "aliyun-cdn",
4613
+ enabled: true,
4614
+ domain,
4615
+ accessKeyId,
4616
+ accessKeySecret,
4617
+ region: process.env.ALIYUN_CDN_REGION
4618
+ };
4619
+ logger9.info("\u2705 \u4ECE\u73AF\u5883\u53D8\u91CF\u52A0\u8F7D CDN \u914D\u7F6E\u6210\u529F", {
4620
+ domain: config.domain
4621
+ });
4622
+ return config;
4623
+ }
4624
+ function getDefaultLocalStorage() {
4625
+ return {
4626
+ type: "local",
4627
+ enabled: true,
4628
+ rootPath: process.env.FILE_STORAGE_PATH || "uploads",
4629
+ baseUrl: process.env.FILE_BASE_URL || "/uploads"
4630
+ };
4631
+ }
4632
+ function loadConfigFromEnv() {
4633
+ logger9.info("\u4ECE\u73AF\u5883\u53D8\u91CF\u52A0\u8F7D\u6587\u4EF6\u670D\u52A1\u914D\u7F6E...");
4634
+ const ossConfig = loadOSSConfigFromEnv();
4635
+ const cdnConfig = loadCDNConfigFromEnv();
4636
+ const storage = ossConfig || getDefaultLocalStorage();
4637
+ const defaultStorage = ossConfig ? "aliyun-oss" : "local";
4638
+ logger9.info(`\u4F7F\u7528\u5B58\u50A8\u65B9\u5F0F: ${defaultStorage}`);
4639
+ const config = {
4640
+ storage,
4641
+ defaultStorage,
4642
+ cdn: cdnConfig || void 0,
4643
+ defaultCDN: cdnConfig ? "aliyun-cdn" : "none",
4644
+ maxFileSize: process.env.MAX_FILE_SIZE ? parseInt(process.env.MAX_FILE_SIZE) : DEFAULT_MAX_FILE_SIZE,
4645
+ allowedMimeTypes: DEFAULT_ALLOWED_MIME_TYPES,
4646
+ cache: {
4647
+ enabled: process.env.ENABLE_CACHE === "true",
4648
+ metadataTTL: process.env.METADATA_CACHE_TTL ? parseInt(process.env.METADATA_CACHE_TTL) : DEFAULT_CACHE_CONFIG.metadataTTL,
4649
+ urlTTL: process.env.URL_CACHE_TTL ? parseInt(process.env.URL_CACHE_TTL) : DEFAULT_CACHE_CONFIG.urlTTL
4650
+ },
4651
+ enableMonitoring: process.env.ENABLE_FILE_MONITORING === "true"
4652
+ };
4653
+ logger9.info("\u2705 \u914D\u7F6E\u52A0\u8F7D\u5B8C\u6210");
4654
+ return config;
4655
+ }
4656
+ var DEFAULT_OSS_CONFIG_KEYS = {
4657
+ region: "aliyun_oss_region",
4658
+ bucket: "aliyun_oss_bucket",
4659
+ accessKeyId: "aliyun_oss_access_key_id",
4660
+ accessKeySecret: "aliyun_oss_access_key_secret",
4661
+ customDomain: "aliyun_oss_custom_domain",
4662
+ secure: "aliyun_oss_secure",
4663
+ internal: "aliyun_oss_internal"
4664
+ };
4665
+ async function loadOSSConfigFromService(configService, keyMapping = DEFAULT_OSS_CONFIG_KEYS) {
4666
+ const logger10 = createLogger("loadOSSConfigFromService");
4667
+ try {
4668
+ const keys = { ...DEFAULT_OSS_CONFIG_KEYS, ...keyMapping };
4669
+ const [region, bucket, accessKeyId, accessKeySecret, customDomain, secure, internal] = await Promise.all([
4670
+ configService.getConfig(keys.region),
4671
+ configService.getConfig(keys.bucket),
4672
+ configService.getConfig(keys.accessKeyId),
4673
+ configService.getConfig(keys.accessKeySecret),
4674
+ configService.getConfig(keys.customDomain || ""),
4675
+ configService.getConfig(keys.secure || ""),
4676
+ configService.getConfig(keys.internal || "")
4677
+ ]);
4678
+ if (!region || !bucket || !accessKeyId || !accessKeySecret) {
4679
+ logger10.debug("\u914D\u7F6E\u670D\u52A1\u4E2D\u7684 OSS \u914D\u7F6E\u4E0D\u5B8C\u6574");
4680
+ return null;
4681
+ }
4682
+ const config = {
4683
+ type: "aliyun-oss",
4684
+ enabled: true,
4685
+ region,
4686
+ bucket,
4687
+ accessKeyId,
4688
+ accessKeySecret,
4689
+ customDomain,
4690
+ secure: secure === "true" || secure === true,
4691
+ internal: internal === "true" || internal === true
4692
+ };
4693
+ logger10.info("\u2705 \u4ECE\u914D\u7F6E\u670D\u52A1\u52A0\u8F7D OSS \u914D\u7F6E\u6210\u529F");
4694
+ return config;
4695
+ } catch (error) {
4696
+ logger10.warn("\u4ECE\u914D\u7F6E\u670D\u52A1\u52A0\u8F7D OSS \u914D\u7F6E\u5931\u8D25:", error);
4697
+ return null;
4698
+ }
4699
+ }
4700
+ async function loadConfigWithFallback(loaders) {
4701
+ for (const loader of loaders) {
4702
+ try {
4703
+ const config = await loader();
4704
+ if (config) {
4705
+ return config;
4706
+ }
4707
+ } catch (error) {
4708
+ continue;
4709
+ }
4710
+ }
4711
+ return null;
4712
+ }
4713
+ async function createFileServiceWithFactory(options = {}) {
4714
+ const {
4715
+ configLoaders = [() => Promise.resolve(loadConfigFromEnv())],
4716
+ repository,
4717
+ customConfig,
4718
+ autoInitialize = false
4719
+ } = options;
4720
+ const logger10 = createLogger("FileServiceFactory");
4721
+ logger10.info("\u521B\u5EFA\u6587\u4EF6\u670D\u52A1...");
4722
+ let config = null;
4723
+ for (const loader of configLoaders) {
4724
+ try {
4725
+ const loadedConfig = await loader();
4726
+ if (loadedConfig) {
4727
+ config = loadedConfig;
4728
+ break;
4729
+ }
4730
+ } catch (error) {
4731
+ logger10.warn("\u914D\u7F6E\u52A0\u8F7D\u5668\u5931\u8D25:", error);
4732
+ continue;
4733
+ }
4734
+ }
4735
+ if (!config) {
4736
+ throw new Error("\u65E0\u6CD5\u52A0\u8F7D\u6587\u4EF6\u670D\u52A1\u914D\u7F6E\uFF1A\u6240\u6709\u914D\u7F6E\u6E90\u90FD\u5931\u8D25");
4737
+ }
4738
+ const finalConfig = {
4739
+ ...config,
4740
+ ...customConfig
4741
+ };
4742
+ if (repository) {
4743
+ finalConfig.persistence = {
4744
+ enabled: true,
4745
+ repository,
4746
+ autoPersist: true
4747
+ };
4748
+ }
4749
+ const service = new UniversalFileService(finalConfig);
4750
+ if (autoInitialize) {
4751
+ await service.initialize();
4752
+ logger10.info("\u2705 \u6587\u4EF6\u670D\u52A1\u521B\u5EFA\u5E76\u521D\u59CB\u5316\u5B8C\u6210");
4753
+ } else {
4754
+ logger10.info("\u2705 \u6587\u4EF6\u670D\u52A1\u521B\u5EFA\u5B8C\u6210");
4755
+ }
4756
+ return service;
4757
+ }
4758
+ function createSingleton(factory, options = {}) {
4759
+ const { autoInitialize = true, name = "Singleton" } = options;
4760
+ const singletonLogger = createLogger(name);
4761
+ let instance = null;
4762
+ let initPromise = null;
4763
+ return {
4764
+ async get() {
4765
+ if (instance) {
4766
+ return instance;
4767
+ }
4768
+ if (initPromise) {
4769
+ singletonLogger.debug("\u7B49\u5F85\u5B9E\u4F8B\u521D\u59CB\u5316\u5B8C\u6210...");
4770
+ return initPromise;
4771
+ }
4772
+ singletonLogger.info("\u521B\u5EFA\u5355\u4F8B\u5B9E\u4F8B...");
4773
+ initPromise = factory();
4774
+ try {
4775
+ instance = await initPromise;
4776
+ singletonLogger.info("\u2705 \u5355\u4F8B\u5B9E\u4F8B\u521B\u5EFA\u5B8C\u6210");
4777
+ return instance;
4778
+ } catch (error) {
4779
+ singletonLogger.error("\u274C \u5355\u4F8B\u5B9E\u4F8B\u521B\u5EFA\u5931\u8D25:", error);
4780
+ initPromise = null;
4781
+ throw error;
4782
+ }
4783
+ },
4784
+ reset() {
4785
+ if (instance) {
4786
+ singletonLogger.info("\u91CD\u7F6E\u5355\u4F8B\u5B9E\u4F8B");
4787
+ instance = null;
4788
+ initPromise = null;
4789
+ }
4790
+ },
4791
+ isCreated() {
4792
+ return instance !== null;
4793
+ }
4794
+ };
4795
+ }
4796
+ var fileStorageProviders = pgTable(
4797
+ "file_storage_providers",
4798
+ {
4799
+ /** 主键ID */
4800
+ id: serial("id").primaryKey(),
4801
+ /** 提供者名称 */
4802
+ name: varchar("name", { length: 100 }).notNull().unique(),
4803
+ /** 提供者类型:local, aliyun_oss, aws_s3, qiniu, etc. */
4804
+ type: varchar("type", { length: 50 }).notNull(),
4805
+ /** 提供者配置(JSON格式存储具体配置信息) */
4806
+ config: json("config").notNull(),
4807
+ /** 是否启用 */
4808
+ isActive: boolean("is_active").notNull().default(true),
4809
+ /** 是否为默认提供者 */
4810
+ isDefault: boolean("is_default").notNull().default(false),
4811
+ /** 优先级(数字越小优先级越高) */
4812
+ priority: integer("priority").notNull().default(100),
4813
+ /** 最大文件大小限制(字节) */
4814
+ maxFileSize: bigint("max_file_size", { mode: "number" }),
4815
+ /** 支持的文件类型(MIME类型列表) */
4816
+ supportedMimeTypes: json("supported_mime_types"),
4817
+ /** 创建时间 */
4818
+ createdAt: timestamp("created_at").defaultNow().notNull(),
4819
+ /** 更新时间 */
4820
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
4821
+ },
4822
+ (table) => ({
4823
+ /** 按类型查询的索引 */
4824
+ typeIndex: index("storage_providers_type_idx").on(table.type),
4825
+ /** 按活跃状态查询的索引 */
4826
+ isActiveIndex: index("storage_providers_is_active_idx").on(table.isActive),
4827
+ /** 按优先级排序的索引 */
4828
+ priorityIndex: index("storage_providers_priority_idx").on(table.priority)
4829
+ })
4830
+ );
4831
+ var fileFolders = pgTable(
4832
+ "file_folders",
4833
+ {
4834
+ /** 主键ID */
4835
+ id: uuid("id").primaryKey().defaultRandom(),
4836
+ /** 文件夹名称 */
4837
+ name: varchar("name", { length: 255 }).notNull(),
4838
+ /** 父文件夹ID(为null表示根文件夹) */
4839
+ parentId: uuid("parent_id"),
4840
+ /** 模块ID(标识属于哪个模块) */
4841
+ moduleId: varchar("module_id", { length: 100 }),
4842
+ /** 业务ID(具体业务实体的ID) */
4843
+ businessId: varchar("business_id", { length: 255 }),
4844
+ /** 文件夹路径(从根到当前文件夹的完整路径) */
4845
+ path: text("path").notNull(),
4846
+ /** 层级深度 */
4847
+ depth: integer("depth").notNull().default(0),
4848
+ /** 显示顺序 */
4849
+ sortOrder: integer("sort_order").notNull().default(0),
4850
+ /** 文件夹描述 */
4851
+ description: text("description"),
4852
+ /** 是否为系统文件夹 */
4853
+ isSystem: boolean("is_system").notNull().default(false),
4854
+ /** 创建者ID */
4855
+ createdBy: varchar("created_by", { length: 255 }).notNull(),
4856
+ /** 创建时间 */
4857
+ createdAt: timestamp("created_at").defaultNow().notNull(),
4858
+ /** 更新时间 */
4859
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
4860
+ },
4861
+ (table) => ({
4862
+ /** 按模块查询的索引 */
4863
+ moduleIndex: index("folders_module_idx").on(table.moduleId),
4864
+ /** 按业务ID查询的索引 */
4865
+ businessIndex: index("folders_business_idx").on(table.businessId),
4866
+ /** 按父文件夹查询的索引 */
4867
+ parentIndex: index("folders_parent_idx").on(table.parentId),
4868
+ /** 按路径查询的索引 */
4869
+ pathIndex: index("folders_path_idx").on(table.path),
4870
+ /** 组合索引:模块+业务+父文件夹 */
4871
+ moduleBusinessParentIndex: index("folders_module_business_parent_idx").on(
4872
+ table.moduleId,
4873
+ table.businessId,
4874
+ table.parentId
4875
+ )
4876
+ })
4877
+ );
4878
+ var fileMetadata = pgTable(
4879
+ "file_metadata",
4880
+ {
4881
+ /** 主键ID */
4882
+ id: uuid("id").primaryKey().defaultRandom(),
4883
+ /** 原始文件名 */
4884
+ originalName: varchar("original_name", { length: 500 }).notNull(),
4885
+ /** 存储文件名(系统生成的唯一文件名) */
4886
+ storedName: varchar("stored_name", { length: 500 }).notNull(),
4887
+ /** 文件扩展名 */
4888
+ extension: varchar("extension", { length: 20 }),
4889
+ /** MIME类型 */
4890
+ mimeType: varchar("mime_type", { length: 100 }).notNull(),
4891
+ /** 文件大小(字节) */
4892
+ size: bigint("size", { mode: "number" }).notNull(),
4893
+ /** 文件MD5哈希值(用于去重和完整性校验) */
4894
+ md5Hash: varchar("md5_hash", { length: 32 }).notNull(),
4895
+ /** 文件SHA256哈希值 */
4896
+ sha256Hash: varchar("sha256_hash", { length: 64 }),
4897
+ /** 存储提供者ID */
4898
+ storageProviderId: integer("storage_provider_id").references(() => fileStorageProviders.id).notNull(),
4899
+ /** 存储路径 */
4900
+ storagePath: text("storage_path").notNull(),
4901
+ /** CDN访问URL */
4902
+ cdnUrl: text("cdn_url"),
4903
+ /** 所属文件夹ID */
4904
+ folderId: uuid("folder_id").references(() => fileFolders.id, { onDelete: "set null" }),
4905
+ /** 模块ID */
4906
+ moduleId: varchar("module_id", { length: 100 }),
4907
+ /** 业务ID */
4908
+ businessId: varchar("business_id", { length: 255 }),
4909
+ /** 文件标签(JSON数组) */
4910
+ tags: json("tags"),
4911
+ /** 文件元信息(如图片尺寸、视频时长等) */
4912
+ metadata: json("metadata"),
4913
+ /** 是否为临时文件 */
4914
+ isTemporary: boolean("is_temporary").notNull().default(false),
4915
+ /** 是否已删除(软删除) */
4916
+ isDeleted: boolean("is_deleted").notNull().default(false),
4917
+ /** 访问次数 */
4918
+ accessCount: integer("access_count").notNull().default(0),
4919
+ /** 下载次数 */
4920
+ downloadCount: integer("download_count").notNull().default(0),
4921
+ /** 上传者ID */
4922
+ uploaderId: varchar("uploader_id", { length: 255 }).notNull(),
4923
+ /** 上传时间 */
4924
+ uploadTime: timestamp("upload_time").defaultNow().notNull(),
4925
+ /** 最后访问时间 */
4926
+ lastAccessTime: timestamp("last_access_time"),
4927
+ /** 过期时间(为null表示永不过期) */
4928
+ expiresAt: timestamp("expires_at"),
4929
+ /** 创建时间 */
4930
+ createdAt: timestamp("created_at").defaultNow().notNull(),
4931
+ /** 更新时间 */
4932
+ updatedAt: timestamp("updated_at").defaultNow().notNull(),
4933
+ /** 删除时间 */
4934
+ deletedAt: timestamp("deleted_at")
4935
+ },
4936
+ (table) => ({
4937
+ /** 按MD5哈希查询的索引(去重用) */
4938
+ md5Index: index("file_metadata_md5_idx").on(table.md5Hash),
4939
+ /** 按SHA256哈希查询的索引 */
4940
+ sha256Index: index("file_metadata_sha256_idx").on(table.sha256Hash),
4941
+ /** 按模块查询的索引 */
4942
+ moduleIndex: index("file_metadata_module_idx").on(table.moduleId),
4943
+ /** 按业务ID查询的索引 */
4944
+ businessIndex: index("file_metadata_business_idx").on(table.businessId),
4945
+ /** 按上传者查询的索引 */
4946
+ uploaderIndex: index("file_metadata_uploader_idx").on(table.uploaderId),
4947
+ /** 按MIME类型查询的索引 */
4948
+ mimeTypeIndex: index("file_metadata_mime_type_idx").on(table.mimeType),
4949
+ /** 按删除状态查询的索引 */
4950
+ isDeletedIndex: index("file_metadata_is_deleted_idx").on(table.isDeleted),
4951
+ /** 按临时状态查询的索引 */
4952
+ isTemporaryIndex: index("file_metadata_is_temporary_idx").on(table.isTemporary),
4953
+ /** 按文件夹查询的索引 */
4954
+ folderIndex: index("file_metadata_folder_idx").on(table.folderId),
4955
+ /** 按上传时间查询的索引 */
4956
+ uploadTimeIndex: index("file_metadata_upload_time_idx").on(table.uploadTime),
4957
+ /** 组合索引:模块+业务+删除状态 */
4958
+ moduleBusinessDeletedIndex: index("file_metadata_module_business_deleted_idx").on(
4959
+ table.moduleId,
4960
+ table.businessId,
4961
+ table.isDeleted
4962
+ ),
4963
+ /** 组合索引:文件夹+删除状态 */
4964
+ folderDeletedIndex: index("file_metadata_folder_deleted_idx").on(
4965
+ table.folderId,
4966
+ table.isDeleted
4967
+ )
4968
+ })
4969
+ );
4970
+ var fileVersions = pgTable(
4971
+ "file_versions",
4972
+ {
4973
+ /** 主键ID */
4974
+ id: uuid("id").primaryKey().defaultRandom(),
4975
+ /** 关联的文件ID */
4976
+ fileId: uuid("file_id").references(() => fileMetadata.id, { onDelete: "cascade" }).notNull(),
4977
+ /** 版本号 */
4978
+ version: integer("version").notNull(),
4979
+ /** 版本描述 */
4980
+ description: text("description"),
4981
+ /** 文件大小 */
4982
+ size: bigint("size", { mode: "number" }).notNull(),
4983
+ /** MD5哈希值 */
4984
+ md5Hash: varchar("md5_hash", { length: 32 }).notNull(),
4985
+ /** 存储路径 */
4986
+ storagePath: text("storage_path").notNull(),
4987
+ /** CDN访问URL */
4988
+ cdnUrl: text("cdn_url"),
4989
+ /** 是否为当前版本 */
4990
+ isCurrent: boolean("is_current").notNull().default(false),
4991
+ /** 创建者ID */
4992
+ createdBy: varchar("created_by", { length: 255 }).notNull(),
4993
+ /** 创建时间 */
4994
+ createdAt: timestamp("created_at").defaultNow().notNull()
4995
+ },
4996
+ (table) => ({
4997
+ /** 按文件ID查询的索引 */
4998
+ fileIndex: index("file_versions_file_idx").on(table.fileId),
4999
+ /** 按当前版本查询的索引 */
5000
+ isCurrentIndex: index("file_versions_is_current_idx").on(table.isCurrent),
5001
+ /** 组合索引:文件+版本 */
5002
+ fileVersionIndex: index("file_versions_file_version_idx").on(table.fileId, table.version)
5003
+ })
5004
+ );
5005
+ var fileProcessingRecords = pgTable(
5006
+ "file_processing_records",
5007
+ {
5008
+ /** 主键ID */
5009
+ id: uuid("id").primaryKey().defaultRandom(),
5010
+ /** 关联的文件ID */
5011
+ fileId: uuid("file_id").references(() => fileMetadata.id, { onDelete: "cascade" }).notNull(),
5012
+ /** 处理类型:compress, resize, convert, thumbnail, watermark, etc. */
5013
+ processingType: varchar("processing_type", { length: 50 }).notNull(),
5014
+ /** 处理器名称 */
5015
+ processorName: varchar("processor_name", { length: 100 }).notNull(),
5016
+ /** 处理状态:pending, processing, completed, failed */
5017
+ status: varchar("status", { length: 20 }).notNull().default("pending"),
5018
+ /** 处理参数(JSON格式) */
5019
+ parameters: json("parameters"),
5020
+ /** 处理结果(JSON格式) */
5021
+ result: json("result"),
5022
+ /** 输出文件路径 */
5023
+ outputPath: text("output_path"),
5024
+ /** 输出文件大小 */
5025
+ outputSize: bigint("output_size", { mode: "number" }),
5026
+ /** 处理耗时(毫秒) */
5027
+ processingTimeMs: integer("processing_time_ms"),
5028
+ /** 错误信息 */
5029
+ errorMessage: text("error_message"),
5030
+ /** 重试次数 */
5031
+ retryCount: integer("retry_count").notNull().default(0),
5032
+ /** 优先级 */
5033
+ priority: integer("priority").notNull().default(5),
5034
+ /** 开始时间 */
5035
+ startedAt: timestamp("started_at"),
5036
+ /** 完成时间 */
5037
+ completedAt: timestamp("completed_at"),
5038
+ /** 创建时间 */
5039
+ createdAt: timestamp("created_at").defaultNow().notNull(),
5040
+ /** 更新时间 */
5041
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5042
+ },
5043
+ (table) => ({
5044
+ /** 按文件ID查询的索引 */
5045
+ fileIndex: index("file_processing_records_file_idx").on(table.fileId),
5046
+ /** 按处理状态查询的索引 */
5047
+ statusIndex: index("file_processing_records_status_idx").on(table.status),
5048
+ /** 按处理类型查询的索引 */
5049
+ processingTypeIndex: index("file_processing_records_processing_type_idx").on(
5050
+ table.processingType
5051
+ ),
5052
+ /** 按优先级查询的索引 */
5053
+ priorityIndex: index("file_processing_records_priority_idx").on(table.priority),
5054
+ /** 组合索引:文件+处理类型 */
5055
+ fileProcessingTypeIndex: index("file_processing_records_file_processing_type_idx").on(
5056
+ table.fileId,
5057
+ table.processingType
5058
+ )
5059
+ })
5060
+ );
5061
+ var fileShares = pgTable(
5062
+ "file_shares",
5063
+ {
5064
+ /** 主键ID */
5065
+ id: uuid("id").primaryKey().defaultRandom(),
5066
+ /** 分享代码(短链接标识) */
5067
+ shareCode: varchar("share_code", { length: 20 }).notNull().unique(),
5068
+ /** 分享的文件ID列表(JSON数组) */
5069
+ fileIds: json("file_ids").notNull(),
5070
+ /** 分享标题 */
5071
+ title: varchar("title", { length: 255 }),
5072
+ /** 分享描述 */
5073
+ description: text("description"),
5074
+ /** 访问密码 */
5075
+ password: varchar("password", { length: 100 }),
5076
+ /** 访问权限:view, download */
5077
+ permission: varchar("permission", { length: 20 }).notNull().default("view"),
5078
+ /** 最大下载次数(为null表示无限制) */
5079
+ maxDownloads: integer("max_downloads"),
5080
+ /** 当前下载次数 */
5081
+ downloadCount: integer("download_count").notNull().default(0),
5082
+ /** 最大访问次数(为null表示无限制) */
5083
+ maxAccess: integer("max_access"),
5084
+ /** 当前访问次数 */
5085
+ accessCount: integer("access_count").notNull().default(0),
5086
+ /** 是否启用 */
5087
+ isActive: boolean("is_active").notNull().default(true),
5088
+ /** 过期时间 */
5089
+ expiresAt: timestamp("expires_at"),
5090
+ /** 创建者ID */
5091
+ createdBy: varchar("created_by", { length: 255 }).notNull(),
5092
+ /** 创建时间 */
5093
+ createdAt: timestamp("created_at").defaultNow().notNull(),
5094
+ /** 更新时间 */
5095
+ updatedAt: timestamp("updated_at").defaultNow().notNull()
5096
+ },
5097
+ (table) => ({
5098
+ /** 按分享代码查询的索引 */
5099
+ shareCodeIndex: index("file_shares_share_code_idx").on(table.shareCode),
5100
+ /** 按创建者查询的索引 */
5101
+ createdByIndex: index("file_shares_created_by_idx").on(table.createdBy),
5102
+ /** 按活跃状态查询的索引 */
5103
+ isActiveIndex: index("file_shares_is_active_idx").on(table.isActive),
5104
+ /** 按过期时间查询的索引 */
5105
+ expiresAtIndex: index("file_shares_expires_at_idx").on(table.expiresAt)
5106
+ })
5107
+ );
5108
+ var fileAccessLogs = pgTable(
5109
+ "file_access_logs",
5110
+ {
5111
+ /** 主键ID */
5112
+ id: uuid("id").primaryKey().defaultRandom(),
5113
+ /** 关联的文件ID */
5114
+ fileId: uuid("file_id").references(() => fileMetadata.id, { onDelete: "cascade" }),
5115
+ /** 分享ID(如果通过分享访问) */
5116
+ shareId: uuid("share_id").references(() => fileShares.id, { onDelete: "set null" }),
5117
+ /** 访问类型:view, download, preview, thumbnail */
5118
+ accessType: varchar("access_type", { length: 20 }).notNull(),
5119
+ /** 用户ID */
5120
+ userId: varchar("user_id", { length: 255 }),
5121
+ /** 客户端IP地址 */
5122
+ ipAddress: varchar("ip_address", { length: 45 }),
5123
+ /** 用户代理字符串 */
5124
+ userAgent: text("user_agent"),
5125
+ /** 访问来源 */
5126
+ referer: text("referer"),
5127
+ /** 响应状态码 */
5128
+ statusCode: integer("status_code"),
5129
+ /** 传输字节数 */
5130
+ bytesTransferred: bigint("bytes_transferred", { mode: "number" }),
5131
+ /** 响应时间(毫秒) */
5132
+ responseTimeMs: integer("response_time_ms"),
5133
+ /** 访问时间 */
5134
+ accessedAt: timestamp("accessed_at").defaultNow().notNull()
5135
+ },
5136
+ (table) => ({
5137
+ /** 按文件ID查询的索引 */
5138
+ fileIndex: index("file_access_logs_file_idx").on(table.fileId),
5139
+ /** 按用户ID查询的索引 */
5140
+ userIndex: index("file_access_logs_user_idx").on(table.userId),
5141
+ /** 按访问类型查询的索引 */
5142
+ accessTypeIndex: index("file_access_logs_access_type_idx").on(table.accessType),
5143
+ /** 按访问时间查询的索引 */
5144
+ accessedAtIndex: index("file_access_logs_accessed_at_idx").on(table.accessedAt),
5145
+ /** 按分享ID查询的索引 */
5146
+ shareIndex: index("file_access_logs_share_idx").on(table.shareId)
5147
+ })
5148
+ );
5149
+ var fileThumbnails = pgTable(
5150
+ "file_thumbnails",
5151
+ {
5152
+ /** 主键ID */
5153
+ id: uuid("id").primaryKey().defaultRandom(),
5154
+ /** 关联的文件ID */
5155
+ fileId: uuid("file_id").references(() => fileMetadata.id, { onDelete: "cascade" }).notNull(),
5156
+ /** 缩略图类型:thumbnail, preview, poster(视频封面), etc. */
5157
+ type: varchar("type", { length: 50 }).notNull(),
5158
+ /** 缩略图规格:small, medium, large, 或具体尺寸如 "200x200" */
5159
+ size: varchar("size", { length: 20 }).notNull(),
5160
+ /** 缩略图宽度 */
5161
+ width: integer("width"),
5162
+ /** 缩略图高度 */
5163
+ height: integer("height"),
5164
+ /** 缩略图格式:jpg, png, webp, etc. */
5165
+ format: varchar("format", { length: 10 }).notNull(),
5166
+ /** 缩略图文件大小 */
5167
+ fileSize: integer("file_size").notNull(),
5168
+ /** 存储路径 */
5169
+ storagePath: text("storage_path").notNull(),
5170
+ /** CDN访问URL */
5171
+ cdnUrl: text("cdn_url"),
5172
+ /** 生成质量(1-100) */
5173
+ quality: integer("quality").default(85),
5174
+ /** 是否生成成功 */
5175
+ isGenerated: boolean("is_generated").notNull().default(false),
5176
+ /** 生成时间 */
5177
+ generatedAt: timestamp("generated_at"),
5178
+ /** 创建时间 */
5179
+ createdAt: timestamp("created_at").defaultNow().notNull()
5180
+ },
5181
+ (table) => ({
5182
+ /** 按文件ID查询的索引 */
5183
+ fileIndex: index("file_thumbnails_file_idx").on(table.fileId),
5184
+ /** 按类型查询的索引 */
5185
+ typeIndex: index("file_thumbnails_type_idx").on(table.type),
5186
+ /** 按生成状态查询的索引 */
5187
+ isGeneratedIndex: index("file_thumbnails_is_generated_idx").on(table.isGenerated),
5188
+ /** 组合索引:文件+类型+尺寸 */
5189
+ fileTypeSizeIndex: index("file_thumbnails_file_type_size_idx").on(
5190
+ table.fileId,
5191
+ table.type,
5192
+ table.size
5193
+ )
5194
+ })
5195
+ );
5196
+ var fileStorageProvidersRelations = relations(fileStorageProviders, ({ many }) => ({
5197
+ files: many(fileMetadata)
5198
+ }));
5199
+ var fileFoldersRelations = relations(fileFolders, ({ one, many }) => ({
5200
+ parent: one(fileFolders, {
5201
+ fields: [fileFolders.parentId],
5202
+ references: [fileFolders.id]
5203
+ }),
5204
+ children: many(fileFolders),
5205
+ files: many(fileMetadata)
5206
+ }));
5207
+ var fileMetadataRelations = relations(fileMetadata, ({ one, many }) => ({
5208
+ storageProvider: one(fileStorageProviders, {
5209
+ fields: [fileMetadata.storageProviderId],
5210
+ references: [fileStorageProviders.id]
5211
+ }),
5212
+ folder: one(fileFolders, {
5213
+ fields: [fileMetadata.folderId],
5214
+ references: [fileFolders.id]
5215
+ }),
5216
+ versions: many(fileVersions),
5217
+ processingRecords: many(fileProcessingRecords),
5218
+ accessLogs: many(fileAccessLogs),
5219
+ thumbnails: many(fileThumbnails)
5220
+ }));
5221
+ var fileVersionsRelations = relations(fileVersions, ({ one }) => ({
5222
+ file: one(fileMetadata, {
5223
+ fields: [fileVersions.fileId],
5224
+ references: [fileMetadata.id]
5225
+ })
5226
+ }));
5227
+ var fileProcessingRecordsRelations = relations(fileProcessingRecords, ({ one }) => ({
5228
+ file: one(fileMetadata, {
5229
+ fields: [fileProcessingRecords.fileId],
5230
+ references: [fileMetadata.id]
5231
+ })
5232
+ }));
5233
+ var fileSharesRelations = relations(fileShares, ({ many }) => ({
5234
+ accessLogs: many(fileAccessLogs)
5235
+ }));
5236
+ var fileAccessLogsRelations = relations(fileAccessLogs, ({ one }) => ({
5237
+ file: one(fileMetadata, {
5238
+ fields: [fileAccessLogs.fileId],
5239
+ references: [fileMetadata.id]
5240
+ }),
5241
+ share: one(fileShares, {
5242
+ fields: [fileAccessLogs.shareId],
5243
+ references: [fileShares.id]
5244
+ })
5245
+ }));
5246
+ var fileThumbnailsRelations = relations(fileThumbnails, ({ one }) => ({
5247
+ file: one(fileMetadata, {
5248
+ fields: [fileThumbnails.fileId],
5249
+ references: [fileMetadata.id]
5250
+ })
5251
+ }));
5252
+
5253
+ export { AliyunCDNProvider, ApiError, ApiErrorCode, AudioProcessor, CacheManager, CacheStrategyType, CdnCacheStrategy2 as CdnCacheStrategy, ConfigValidationError, DEFAULT_ALLOWED_MIME_TYPES, DEFAULT_CACHE_CONFIG, DEFAULT_FILE_SERVICE_CONFIG, DEFAULT_MAX_FILE_SIZE, DEFAULT_OSS_CONFIG_KEYS, ErrorHttpStatusMap, ErrorMessages, ImageProcessor, PerformanceMonitor, ProcessingQueue, UniversalFileService, VideoProcessor, cdnCacheStrategy, createAliyunOSSPreset, createDocumentServicePreset, createDrizzleRepository, createFileServiceConfig, createFileServiceFromEnv, createFileServiceWithFactory, createImageServicePreset, createLocalDevPreset, createSingleton, createSmartPreset, createUniversalFileService, createVideoServicePreset, fileAccessLogs, fileAccessLogsRelations, fileFolders, fileFoldersRelations, fileMetadata, fileMetadataRelations, fileProcessingRecords, fileProcessingRecordsRelations, fileShares, fileSharesRelations, fileStorageProviders, fileStorageProvidersRelations, fileThumbnails, fileThumbnailsRelations, fileVersions, fileVersionsRelations, getDefaultLocalStorage, getMimeType, getRequiredEnvVars, loadCDNConfigFromEnv, loadConfigFromEnv, loadConfigWithFallback, loadOSSConfigFromEnv, loadOSSConfigFromService, validateEnvironment, validateServiceConfig, validateStorageConfig };
4517
5254
  //# sourceMappingURL=index.mjs.map
4518
5255
  //# sourceMappingURL=index.mjs.map