@nest-omni/core 4.1.3-10 → 4.1.3-12

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 (183) hide show
  1. package/audit/audit.module.js +42 -2
  2. package/audit/controllers/audit.controller.d.ts +64 -0
  3. package/audit/controllers/audit.controller.js +50 -0
  4. package/audit/decorators/audit-action.decorator.d.ts +74 -0
  5. package/audit/decorators/audit-action.decorator.js +42 -0
  6. package/audit/decorators/audit-controller.decorator.d.ts +1 -1
  7. package/audit/decorators/audit-controller.decorator.js +2 -2
  8. package/audit/decorators/entity-audit.decorator.d.ts +78 -2
  9. package/audit/decorators/entity-audit.decorator.js +145 -4
  10. package/audit/decorators/index.d.ts +2 -0
  11. package/audit/decorators/index.js +2 -0
  12. package/audit/entities/audit-action-summary.entity.d.ts +23 -0
  13. package/audit/entities/audit-action-summary.entity.js +101 -0
  14. package/audit/entities/entity-audit-log.entity.d.ts +8 -0
  15. package/audit/entities/entity-audit-log.entity.js +54 -2
  16. package/audit/entities/entity-transaction.entity.d.ts +8 -2
  17. package/audit/entities/entity-transaction.entity.js +39 -3
  18. package/audit/entities/index.d.ts +3 -0
  19. package/audit/entities/index.js +3 -0
  20. package/audit/entities/manual-operation-log.entity.js +8 -1
  21. package/audit/enums/audit.enums.d.ts +22 -6
  22. package/audit/enums/audit.enums.js +27 -9
  23. package/audit/index.d.ts +4 -1
  24. package/audit/index.js +25 -2
  25. package/audit/interceptors/audit-action.interceptor.d.ts +38 -0
  26. package/audit/interceptors/audit-action.interceptor.js +215 -0
  27. package/audit/interceptors/index.d.ts +1 -0
  28. package/audit/interceptors/index.js +1 -0
  29. package/audit/interfaces/audit.interfaces.d.ts +145 -2
  30. package/audit/services/audit-action.service.d.ts +141 -0
  31. package/audit/services/audit-action.service.js +244 -0
  32. package/audit/services/audit-context.service.d.ts +82 -0
  33. package/audit/services/audit-context.service.js +170 -0
  34. package/audit/services/entity-audit.service.d.ts +174 -4
  35. package/audit/services/entity-audit.service.js +515 -14
  36. package/audit/services/index.d.ts +3 -0
  37. package/audit/services/index.js +3 -0
  38. package/audit/services/manual-audit-log.service.d.ts +24 -23
  39. package/audit/services/manual-audit-log.service.js +32 -53
  40. package/audit/services/operation-description.service.d.ts +13 -3
  41. package/audit/services/operation-description.service.js +161 -24
  42. package/audit/services/transaction-audit.service.js +3 -3
  43. package/audit/subscribers/entity-audit.subscriber.d.ts +4 -0
  44. package/audit/subscribers/entity-audit.subscriber.js +47 -0
  45. package/file-upload/controllers/file-access.controller.d.ts +23 -0
  46. package/file-upload/controllers/file-access.controller.js +128 -0
  47. package/file-upload/decorators/csv-data.decorator.d.ts +44 -0
  48. package/file-upload/decorators/csv-data.decorator.js +131 -0
  49. package/file-upload/decorators/excel-data.decorator.d.ts +44 -0
  50. package/file-upload/decorators/excel-data.decorator.js +125 -0
  51. package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
  52. package/file-upload/decorators/file-upload.decorator.js +172 -0
  53. package/file-upload/decorators/index.d.ts +4 -0
  54. package/file-upload/decorators/index.js +20 -0
  55. package/file-upload/decorators/process.decorator.d.ts +40 -0
  56. package/file-upload/decorators/process.decorator.js +52 -0
  57. package/file-upload/dto/create-file.dto.d.ts +24 -0
  58. package/file-upload/dto/create-file.dto.js +112 -0
  59. package/file-upload/dto/find-files.dto.d.ts +15 -0
  60. package/file-upload/dto/find-files.dto.js +76 -0
  61. package/file-upload/dto/index.d.ts +4 -0
  62. package/file-upload/dto/index.js +20 -0
  63. package/file-upload/dto/pagination.dto.d.ts +7 -0
  64. package/file-upload/dto/pagination.dto.js +39 -0
  65. package/file-upload/dto/update-file.dto.d.ts +16 -0
  66. package/file-upload/dto/update-file.dto.js +71 -0
  67. package/file-upload/entities/file-metadata.entity.d.ts +22 -0
  68. package/file-upload/entities/file-metadata.entity.js +84 -0
  69. package/file-upload/entities/file.entity.d.ts +129 -0
  70. package/file-upload/entities/file.entity.js +384 -0
  71. package/file-upload/entities/index.d.ts +2 -0
  72. package/file-upload/entities/index.js +18 -0
  73. package/file-upload/enums/file-type.enum.d.ts +72 -0
  74. package/file-upload/enums/file-type.enum.js +212 -0
  75. package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
  76. package/file-upload/exceptions/file-upload.exception.js +120 -0
  77. package/file-upload/exceptions/index.d.ts +1 -0
  78. package/file-upload/exceptions/index.js +17 -0
  79. package/file-upload/file-upload.module.d.ts +89 -0
  80. package/file-upload/file-upload.module.js +264 -0
  81. package/file-upload/index.d.ts +26 -0
  82. package/file-upload/index.js +59 -0
  83. package/file-upload/interceptors/file-upload.interceptor.d.ts +48 -0
  84. package/file-upload/interceptors/file-upload.interceptor.js +434 -0
  85. package/file-upload/interceptors/index.d.ts +1 -0
  86. package/file-upload/interceptors/index.js +17 -0
  87. package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
  88. package/file-upload/interfaces/custom-file-type.interface.js +2 -0
  89. package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
  90. package/file-upload/interfaces/file-buffer.interface.js +2 -0
  91. package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
  92. package/file-upload/interfaces/file-entity.interface.js +28 -0
  93. package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
  94. package/file-upload/interfaces/file-metadata.interface.js +2 -0
  95. package/file-upload/interfaces/file-upload-options.interface.d.ts +117 -0
  96. package/file-upload/interfaces/file-upload-options.interface.js +2 -0
  97. package/file-upload/interfaces/index.d.ts +7 -0
  98. package/file-upload/interfaces/index.js +24 -0
  99. package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
  100. package/file-upload/interfaces/storage-provider.interface.js +2 -0
  101. package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
  102. package/file-upload/interfaces/upload-options.interface.js +2 -0
  103. package/file-upload/providers/index.d.ts +2 -0
  104. package/file-upload/providers/index.js +18 -0
  105. package/file-upload/providers/local-storage.provider.d.ts +98 -0
  106. package/file-upload/providers/local-storage.provider.js +484 -0
  107. package/file-upload/providers/s3-storage.provider.d.ts +87 -0
  108. package/file-upload/providers/s3-storage.provider.js +455 -0
  109. package/file-upload/services/file-signature-validator.service.d.ts +118 -0
  110. package/file-upload/services/file-signature-validator.service.js +376 -0
  111. package/file-upload/services/file.service.d.ts +190 -0
  112. package/file-upload/services/file.service.js +609 -0
  113. package/file-upload/services/index.d.ts +4 -0
  114. package/file-upload/services/index.js +20 -0
  115. package/file-upload/services/malicious-file-detector.service.d.ts +274 -0
  116. package/file-upload/services/malicious-file-detector.service.js +1035 -0
  117. package/file-upload/services/mime-registry.service.d.ts +47 -0
  118. package/file-upload/services/mime-registry.service.js +167 -0
  119. package/file-upload/utils/checksum.util.d.ts +28 -0
  120. package/file-upload/utils/checksum.util.js +65 -0
  121. package/file-upload/utils/dynamic-import.util.d.ts +50 -0
  122. package/file-upload/utils/dynamic-import.util.js +144 -0
  123. package/file-upload/utils/filename.util.d.ts +59 -0
  124. package/file-upload/utils/filename.util.js +184 -0
  125. package/file-upload/utils/filepath.util.d.ts +70 -0
  126. package/file-upload/utils/filepath.util.js +152 -0
  127. package/file-upload/utils/index.d.ts +4 -0
  128. package/file-upload/utils/index.js +20 -0
  129. package/http-client/http-client.module.js +1 -5
  130. package/index.d.ts +3 -1
  131. package/index.js +4 -1
  132. package/package.json +4 -5
  133. package/redis-lock/lock-heartbeat.service.d.ts +2 -2
  134. package/redis-lock/lock-heartbeat.service.js +4 -4
  135. package/redis-lock/redis-lock.service.d.ts +18 -0
  136. package/redis-lock/redis-lock.service.js +38 -8
  137. package/setup/bootstrap.setup.d.ts +1 -0
  138. package/setup/bootstrap.setup.js +1 -0
  139. package/setup/schedule.decorator.js +18 -8
  140. package/shared/index.d.ts +1 -1
  141. package/shared/index.js +1 -1
  142. package/shared/{serviceRegistryModule.js → service-registry.module.js} +9 -16
  143. package/shared/services/index.d.ts +0 -1
  144. package/shared/services/index.js +0 -1
  145. package/transaction/__tests__/mocks.d.ts +9 -0
  146. package/transaction/__tests__/mocks.js +33 -0
  147. package/transaction/base-service-transaction.d.ts +99 -0
  148. package/transaction/base-service-transaction.js +286 -0
  149. package/transaction/cls-compatibility.service.d.ts +55 -0
  150. package/transaction/cls-compatibility.service.js +127 -0
  151. package/transaction/data-source-registry.d.ts +91 -0
  152. package/transaction/data-source-registry.js +349 -0
  153. package/transaction/database-adapter.d.ts +44 -0
  154. package/transaction/database-adapter.js +240 -0
  155. package/transaction/decorators/entity-datasource.decorator.d.ts +62 -0
  156. package/transaction/decorators/entity-datasource.decorator.js +105 -0
  157. package/transaction/index.d.ts +14 -0
  158. package/transaction/index.js +57 -0
  159. package/transaction/logging-transactional.interceptor.d.ts +18 -0
  160. package/transaction/logging-transactional.interceptor.js +163 -0
  161. package/transaction/transaction-context.service.d.ts +137 -0
  162. package/transaction/transaction-context.service.js +411 -0
  163. package/transaction/transaction-manager.d.ts +230 -0
  164. package/transaction/transaction-manager.js +1001 -0
  165. package/transaction/transaction-synchronization.d.ts +171 -0
  166. package/transaction/transaction-synchronization.js +380 -0
  167. package/transaction/transaction.errors.d.ts +91 -0
  168. package/transaction/transaction.errors.js +206 -0
  169. package/transaction/transaction.module.d.ts +30 -0
  170. package/transaction/transaction.module.js +98 -0
  171. package/transaction/transactional.decorator.d.ts +82 -0
  172. package/transaction/transactional.decorator.js +319 -0
  173. package/transaction/typeorm-module-wrapper.d.ts +96 -0
  174. package/transaction/typeorm-module-wrapper.js +197 -0
  175. package/validators/file-mimetype.validator.d.ts +0 -2
  176. package/validators/file-mimetype.validator.js +4 -6
  177. package/validators/is-exists.validator.d.ts +2 -5
  178. package/validators/is-exists.validator.js +4 -6
  179. package/validators/is-unique.validator.d.ts +2 -5
  180. package/validators/is-unique.validator.js +6 -11
  181. package/shared/services/validator.service.d.ts +0 -3
  182. package/shared/services/validator.service.js +0 -20
  183. /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
@@ -0,0 +1,55 @@
1
+ import { EntityManager } from 'typeorm';
2
+ import { TransactionContextService } from './transaction-context.service';
3
+ /**
4
+ * CLS (Continuation Local Storage) 兼容服务
5
+ * 提供与 nestjs-cls 兼容的 API,但底层使用事务上下文服务
6
+ */
7
+ export declare class ClsCompatibilityService {
8
+ private readonly transactionContext;
9
+ private readonly defaultDataSource?;
10
+ private readonly store;
11
+ constructor(transactionContext: TransactionContextService, defaultDataSource?: string);
12
+ /**
13
+ * 设置值到存储中
14
+ */
15
+ set<T>(key: string, value: T): void;
16
+ /**
17
+ * 从存储中获取值
18
+ */
19
+ get<T>(key: string): T | undefined;
20
+ /**
21
+ * 根据数据源名称获取 EntityManager
22
+ */
23
+ getEntityManager(dataSourceName?: string): EntityManager | null;
24
+ /**
25
+ * 设置指定数据源的 EntityManager
26
+ */
27
+ setEntityManager(dataSourceName: string, entityManager: EntityManager): void;
28
+ /**
29
+ * 检查是否在事务中
30
+ */
31
+ isInTransaction(dataSourceName?: string): boolean;
32
+ /**
33
+ * 获取所有活跃的事务上下文
34
+ */
35
+ getActiveTransactions(): Map<string, {
36
+ entityManager: EntityManager;
37
+ dataSource: any;
38
+ }>;
39
+ /**
40
+ * 清理存储
41
+ */
42
+ clear(): void;
43
+ }
44
+ /**
45
+ * CLS 服务管理器(静态类,模拟 nestjs-cls 的 API)
46
+ */
47
+ export declare class ClsServiceManager {
48
+ private static clsService;
49
+ static setClsService(clsService: ClsCompatibilityService): void;
50
+ static getClsService(): ClsCompatibilityService;
51
+ }
52
+ /**
53
+ * CLS 装饰器(兼容性)
54
+ */
55
+ export declare function SetCls(key?: string): (target: any, propertyKey: string | symbol, parameterIndex: number) => void;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ClsServiceManager = exports.ClsCompatibilityService = void 0;
16
+ exports.SetCls = SetCls;
17
+ const common_1 = require("@nestjs/common");
18
+ const transaction_context_service_1 = require("./transaction-context.service");
19
+ /**
20
+ * CLS (Continuation Local Storage) 兼容服务
21
+ * 提供与 nestjs-cls 兼容的 API,但底层使用事务上下文服务
22
+ */
23
+ let ClsCompatibilityService = class ClsCompatibilityService {
24
+ constructor(transactionContext, defaultDataSource) {
25
+ this.transactionContext = transactionContext;
26
+ this.defaultDataSource = defaultDataSource;
27
+ this.store = new Map();
28
+ }
29
+ /**
30
+ * 设置值到存储中
31
+ */
32
+ set(key, value) {
33
+ if (key === 'entityManager') {
34
+ // 如果设置 entityManager,则根据数据源名称设置到事务上下文
35
+ const dataSourceName = this.defaultDataSource || 'default';
36
+ this.transactionContext.setContext(dataSourceName, value);
37
+ }
38
+ else {
39
+ this.store.set(key, value);
40
+ }
41
+ }
42
+ /**
43
+ * 从存储中获取值
44
+ */
45
+ get(key) {
46
+ if (key === 'entityManager') {
47
+ // 获取默认数据源的 EntityManager
48
+ const dataSourceName = this.defaultDataSource || 'default';
49
+ return this.transactionContext.getEntityManager(dataSourceName);
50
+ }
51
+ else {
52
+ return this.store.get(key);
53
+ }
54
+ }
55
+ /**
56
+ * 根据数据源名称获取 EntityManager
57
+ */
58
+ getEntityManager(dataSourceName) {
59
+ return this.transactionContext.getEntityManager(dataSourceName || this.defaultDataSource || 'default');
60
+ }
61
+ /**
62
+ * 设置指定数据源的 EntityManager
63
+ */
64
+ setEntityManager(dataSourceName, entityManager) {
65
+ this.transactionContext.setContext(dataSourceName, entityManager);
66
+ }
67
+ /**
68
+ * 检查是否在事务中
69
+ */
70
+ isInTransaction(dataSourceName) {
71
+ return this.transactionContext.isInTransaction(dataSourceName || this.defaultDataSource || 'default');
72
+ }
73
+ /**
74
+ * 获取所有活跃的事务上下文
75
+ */
76
+ getActiveTransactions() {
77
+ const contexts = this.transactionContext.getAllActiveContexts();
78
+ const result = new Map();
79
+ for (const [name, context] of contexts) {
80
+ result.set(name, {
81
+ entityManager: context.entityManager,
82
+ dataSource: context.dataSource,
83
+ });
84
+ }
85
+ return result;
86
+ }
87
+ /**
88
+ * 清理存储
89
+ */
90
+ clear() {
91
+ this.store.clear();
92
+ this.transactionContext.clearContext();
93
+ }
94
+ };
95
+ exports.ClsCompatibilityService = ClsCompatibilityService;
96
+ exports.ClsCompatibilityService = ClsCompatibilityService = __decorate([
97
+ (0, common_1.Injectable)({ scope: common_1.Scope.REQUEST }),
98
+ __param(1, (0, common_1.Optional)()),
99
+ __param(1, (0, common_1.Inject)('CLS_DEFAULT_DATA_SOURCE')),
100
+ __metadata("design:paramtypes", [transaction_context_service_1.TransactionContextService, String])
101
+ ], ClsCompatibilityService);
102
+ /**
103
+ * CLS 服务管理器(静态类,模拟 nestjs-cls 的 API)
104
+ */
105
+ class ClsServiceManager {
106
+ static setClsService(clsService) {
107
+ ClsServiceManager.clsService = clsService;
108
+ }
109
+ static getClsService() {
110
+ if (!ClsServiceManager.clsService) {
111
+ throw new Error('CLS service not initialized. Please ensure TransactionModule is imported.');
112
+ }
113
+ return ClsServiceManager.clsService;
114
+ }
115
+ }
116
+ exports.ClsServiceManager = ClsServiceManager;
117
+ ClsServiceManager.clsService = null;
118
+ /**
119
+ * CLS 装饰器(兼容性)
120
+ */
121
+ function SetCls(key) {
122
+ return function (target, propertyKey, parameterIndex) {
123
+ const existing = Reflect.getMetadata('cls_params', target) || {};
124
+ existing[parameterIndex] = { key };
125
+ Reflect.defineMetadata('cls_params', existing, target);
126
+ };
127
+ }
@@ -0,0 +1,91 @@
1
+ import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
2
+ import { DataSource, DataSourceOptions } from 'typeorm';
3
+ /**
4
+ * 数据源注册表配置
5
+ */
6
+ export interface DataSourceRegistryConfig {
7
+ enableHealthCheck?: boolean;
8
+ healthCheckInterval?: number;
9
+ connectionTimeout?: number;
10
+ maxReconnectAttempts?: number;
11
+ logLifecycleEvents?: boolean;
12
+ autoCleanup?: boolean;
13
+ }
14
+ /**
15
+ * 数据源健康状态
16
+ */
17
+ export interface DataSourceHealthStatus {
18
+ name: string;
19
+ isConnected: boolean;
20
+ lastChecked: Date;
21
+ error?: string;
22
+ responseTime?: number;
23
+ }
24
+ /**
25
+ * 数据源注册表管理器
26
+ * 负责管理所有动态注册的数据源
27
+ */
28
+ export declare class DataSourceRegistryService implements OnModuleInit, OnModuleDestroy {
29
+ private readonly logger;
30
+ private healthCheckInterval;
31
+ private healthStatuses;
32
+ private config;
33
+ constructor(config?: DataSourceRegistryConfig);
34
+ onModuleInit(): Promise<void>;
35
+ onModuleDestroy(): Promise<void>;
36
+ /**
37
+ * 注册新的数据源
38
+ */
39
+ registerDataSource(name: string, options: DataSourceOptions, metadata?: Record<string, any>): Promise<DataSource>;
40
+ /**
41
+ * 注册已存在的数据源
42
+ */
43
+ registerExistingDataSource(name: string, dataSource: DataSource, metadata?: Record<string, any>): Promise<void>;
44
+ /**
45
+ * 注销数据源
46
+ */
47
+ unregisterDataSource(name: string): Promise<void>;
48
+ /**
49
+ * 获取数据源
50
+ */
51
+ getDataSource(name: string): DataSource | null;
52
+ /**
53
+ * 获取所有已注册的数据源名称
54
+ */
55
+ getRegisteredDataSources(): string[];
56
+ /**
57
+ * 批量注册数据源
58
+ */
59
+ registerDataSources(configs: Array<{
60
+ name: string;
61
+ options: DataSourceOptions;
62
+ metadata?: Record<string, any>;
63
+ }>, options?: {
64
+ continueOnError?: boolean;
65
+ parallel?: boolean;
66
+ }): Promise<DataSource[]>;
67
+ /**
68
+ * 测试数据源连接
69
+ */
70
+ testConnection(name: string): Promise<boolean>;
71
+ /**
72
+ * 获取所有数据源的健康状态
73
+ */
74
+ getHealthStatuses(): Map<string, DataSourceHealthStatus>;
75
+ /**
76
+ * 重新连接数据源
77
+ */
78
+ reconnectDataSource(name: string): Promise<boolean>;
79
+ /**
80
+ * 开始健康检查
81
+ */
82
+ private startHealthCheck;
83
+ /**
84
+ * 清理指定数据源
85
+ */
86
+ private cleanupDataSources;
87
+ /**
88
+ * 清理所有动态数据源
89
+ */
90
+ private cleanupAllDataSources;
91
+ }
@@ -0,0 +1,349 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var DataSourceRegistryService_1;
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.DataSourceRegistryService = void 0;
26
+ const common_1 = require("@nestjs/common");
27
+ const typeorm_1 = require("typeorm");
28
+ const transaction_context_service_1 = require("./transaction-context.service");
29
+ const database_adapter_1 = require("./database-adapter");
30
+ /**
31
+ * 数据源注册表管理器
32
+ * 负责管理所有动态注册的数据源
33
+ */
34
+ let DataSourceRegistryService = DataSourceRegistryService_1 = class DataSourceRegistryService {
35
+ constructor(config) {
36
+ this.logger = new common_1.Logger(DataSourceRegistryService_1.name);
37
+ this.healthCheckInterval = null;
38
+ this.healthStatuses = new Map();
39
+ this.config = {
40
+ enableHealthCheck: false,
41
+ healthCheckInterval: 30000, // 30秒
42
+ connectionTimeout: 5000, // 5秒
43
+ maxReconnectAttempts: 3,
44
+ logLifecycleEvents: true,
45
+ autoCleanup: true,
46
+ };
47
+ if (config) {
48
+ this.config = Object.assign(Object.assign({}, this.config), config);
49
+ }
50
+ }
51
+ onModuleInit() {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ if (this.config.enableHealthCheck) {
54
+ this.startHealthCheck();
55
+ }
56
+ if (this.config.logLifecycleEvents) {
57
+ this.logger.log(`Initialized with config: ${JSON.stringify(this.config)}`);
58
+ }
59
+ });
60
+ }
61
+ onModuleDestroy() {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ if (this.healthCheckInterval) {
64
+ clearInterval(this.healthCheckInterval);
65
+ this.healthCheckInterval = null;
66
+ }
67
+ // 清理所有动态注册的数据源
68
+ yield this.cleanupAllDataSources();
69
+ });
70
+ }
71
+ /**
72
+ * 注册新的数据源
73
+ */
74
+ registerDataSource(name, options, metadata) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ try {
77
+ // 创建数据源
78
+ const dataSource = new typeorm_1.DataSource(options);
79
+ // 初始化连接
80
+ if (!dataSource.isInitialized) {
81
+ yield dataSource.initialize();
82
+ }
83
+ // 注册到事务上下文服务
84
+ yield transaction_context_service_1.TransactionContextService.addDataSource(name, dataSource, {
85
+ options,
86
+ metadata,
87
+ });
88
+ // 初始化健康状态
89
+ if (this.config.enableHealthCheck) {
90
+ this.healthStatuses.set(name, {
91
+ name,
92
+ isConnected: true,
93
+ lastChecked: new Date(),
94
+ });
95
+ }
96
+ if (this.config.logLifecycleEvents) {
97
+ this.logger.log(`Registered DataSource: ${name}`);
98
+ }
99
+ return dataSource;
100
+ }
101
+ catch (error) {
102
+ this.logger.error(`Failed to register DataSource ${name}:`, error.stack);
103
+ throw error;
104
+ }
105
+ });
106
+ }
107
+ /**
108
+ * 注册已存在的数据源
109
+ */
110
+ registerExistingDataSource(name, dataSource, metadata) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ yield transaction_context_service_1.TransactionContextService.addDataSource(name, dataSource, {
113
+ metadata,
114
+ });
115
+ if (this.config.enableHealthCheck) {
116
+ this.healthStatuses.set(name, {
117
+ name,
118
+ isConnected: dataSource.isInitialized,
119
+ lastChecked: new Date(),
120
+ });
121
+ }
122
+ });
123
+ }
124
+ /**
125
+ * 注销数据源
126
+ */
127
+ unregisterDataSource(name) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ const config = transaction_context_service_1.TransactionContextService.getDataSourceConfig(name);
130
+ if (config) {
131
+ // 关闭数据源连接
132
+ if (config.dataSource.isInitialized) {
133
+ yield config.dataSource.destroy();
134
+ }
135
+ // 从注册表中移除
136
+ yield transaction_context_service_1.TransactionContextService.removeDataSource(name);
137
+ this.healthStatuses.delete(name);
138
+ if (this.config.logLifecycleEvents) {
139
+ this.logger.log(`Unregistered DataSource: ${name}`);
140
+ }
141
+ }
142
+ });
143
+ }
144
+ /**
145
+ * 获取数据源
146
+ */
147
+ getDataSource(name) {
148
+ const config = transaction_context_service_1.TransactionContextService.getDataSourceConfig(name);
149
+ return (config === null || config === void 0 ? void 0 : config.dataSource) || null;
150
+ }
151
+ /**
152
+ * 获取所有已注册的数据源名称
153
+ */
154
+ getRegisteredDataSources() {
155
+ return transaction_context_service_1.TransactionContextService.getRegisteredDataSources();
156
+ }
157
+ /**
158
+ * 批量注册数据源
159
+ */
160
+ registerDataSources(configs, options) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ const dataSources = [];
163
+ if (options === null || options === void 0 ? void 0 : options.parallel) {
164
+ // 并行注册
165
+ const promises = configs.map((config) => __awaiter(this, void 0, void 0, function* () {
166
+ const ds = yield this.registerDataSource(config.name, config.options, config.metadata);
167
+ return ds;
168
+ }));
169
+ try {
170
+ const results = yield Promise.all(promises);
171
+ dataSources.push(...results);
172
+ }
173
+ catch (error) {
174
+ if (!(options === null || options === void 0 ? void 0 : options.continueOnError)) {
175
+ // 清理已注册的数据源
176
+ yield this.cleanupDataSources(dataSources.map((ds) => ds.options));
177
+ throw error;
178
+ }
179
+ }
180
+ }
181
+ else {
182
+ // 串行注册
183
+ for (const config of configs) {
184
+ try {
185
+ const ds = yield this.registerDataSource(config.name, config.options, config.metadata);
186
+ dataSources.push(ds);
187
+ }
188
+ catch (error) {
189
+ if (!(options === null || options === void 0 ? void 0 : options.continueOnError)) {
190
+ // 清理已注册的数据源
191
+ yield this.cleanupDataSources(dataSources.map((ds) => ds.options));
192
+ throw error;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ return dataSources;
198
+ });
199
+ }
200
+ /**
201
+ * 测试数据源连接
202
+ */
203
+ testConnection(name) {
204
+ return __awaiter(this, void 0, void 0, function* () {
205
+ const config = transaction_context_service_1.TransactionContextService.getDataSourceConfig(name);
206
+ if (!config) {
207
+ return false;
208
+ }
209
+ const startTime = Date.now();
210
+ try {
211
+ // 使用数据库适配器执行健康检查
212
+ const isHealthy = yield database_adapter_1.DatabaseAdapter.healthCheck(config.dataSource);
213
+ const responseTime = Date.now() - startTime;
214
+ if (!isHealthy) {
215
+ throw new Error('Health check query failed');
216
+ }
217
+ // 更新健康状态
218
+ if (this.config.enableHealthCheck) {
219
+ this.healthStatuses.set(name, {
220
+ name,
221
+ isConnected: true,
222
+ lastChecked: new Date(),
223
+ responseTime,
224
+ });
225
+ }
226
+ return true;
227
+ }
228
+ catch (error) {
229
+ // 更新健康状态
230
+ if (this.config.enableHealthCheck) {
231
+ this.healthStatuses.set(name, {
232
+ name,
233
+ isConnected: false,
234
+ lastChecked: new Date(),
235
+ error: error.message,
236
+ responseTime: Date.now() - startTime,
237
+ });
238
+ }
239
+ return false;
240
+ }
241
+ });
242
+ }
243
+ /**
244
+ * 获取所有数据源的健康状态
245
+ */
246
+ getHealthStatuses() {
247
+ return new Map(this.healthStatuses);
248
+ }
249
+ /**
250
+ * 重新连接数据源
251
+ */
252
+ reconnectDataSource(name) {
253
+ return __awaiter(this, void 0, void 0, function* () {
254
+ const config = transaction_context_service_1.TransactionContextService.getDataSourceConfig(name);
255
+ if (!config || !config.options) {
256
+ throw new Error(`Cannot reconnect: DataSource '${name}' has no connection options`);
257
+ }
258
+ try {
259
+ // 关闭现有连接
260
+ if (config.dataSource.isInitialized) {
261
+ yield config.dataSource.destroy();
262
+ }
263
+ // 重新初始化
264
+ yield config.dataSource.initialize();
265
+ // 测试连接
266
+ const isConnected = yield this.testConnection(name);
267
+ if (this.config.logLifecycleEvents) {
268
+ this.logger.log(`Reconnected DataSource: ${name}, Success: ${isConnected}`);
269
+ }
270
+ return isConnected;
271
+ }
272
+ catch (error) {
273
+ this.logger.error(`Failed to reconnect DataSource ${name}:`, error.stack);
274
+ return false;
275
+ }
276
+ });
277
+ }
278
+ /**
279
+ * 开始健康检查
280
+ */
281
+ startHealthCheck() {
282
+ this.healthCheckInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
283
+ var _a;
284
+ const dataSources = this.getRegisteredDataSources();
285
+ for (const name of dataSources) {
286
+ yield this.testConnection(name);
287
+ // 自动重连
288
+ const status = this.healthStatuses.get(name);
289
+ if (!(status === null || status === void 0 ? void 0 : status.isConnected) && this.config.autoCleanup) {
290
+ this.logger.warn(`DataSource ${name} is unhealthy, attempting reconnect...`);
291
+ let attempts = 0;
292
+ const maxAttempts = this.config.maxReconnectAttempts || 3;
293
+ while (attempts < maxAttempts) {
294
+ const reconnected = yield this.reconnectDataSource(name);
295
+ if (reconnected) {
296
+ break;
297
+ }
298
+ attempts++;
299
+ }
300
+ if (!((_a = this.healthStatuses.get(name)) === null || _a === void 0 ? void 0 : _a.isConnected)) {
301
+ this.logger.error(`Failed to reconnect DataSource ${name} after ${maxAttempts} attempts`);
302
+ }
303
+ }
304
+ }
305
+ }), this.config.healthCheckInterval);
306
+ this.logger.log('Health check started');
307
+ }
308
+ /**
309
+ * 清理指定数据源
310
+ */
311
+ cleanupDataSources(options) {
312
+ return __awaiter(this, void 0, void 0, function* () {
313
+ // 找到对应的数据源并清理
314
+ for (const opt of options) {
315
+ // 这里需要从配置反向查找数据源名称
316
+ // 简化实现:遍历所有已注册的数据源
317
+ const names = this.getRegisteredDataSources();
318
+ for (const name of names) {
319
+ const config = transaction_context_service_1.TransactionContextService.getDataSourceConfig(name);
320
+ if ((config === null || config === void 0 ? void 0 : config.dataSource.options) === opt) {
321
+ yield this.unregisterDataSource(name);
322
+ break;
323
+ }
324
+ }
325
+ }
326
+ });
327
+ }
328
+ /**
329
+ * 清理所有动态数据源
330
+ */
331
+ cleanupAllDataSources() {
332
+ return __awaiter(this, void 0, void 0, function* () {
333
+ const names = this.getRegisteredDataSources();
334
+ for (const name of names) {
335
+ yield this.unregisterDataSource(name);
336
+ }
337
+ if (this.config.logLifecycleEvents) {
338
+ this.logger.log('All dynamic DataSources cleaned up');
339
+ }
340
+ });
341
+ }
342
+ };
343
+ exports.DataSourceRegistryService = DataSourceRegistryService;
344
+ exports.DataSourceRegistryService = DataSourceRegistryService = DataSourceRegistryService_1 = __decorate([
345
+ (0, common_1.Injectable)(),
346
+ __param(0, (0, common_1.Optional)()),
347
+ __param(0, (0, common_1.Inject)('DATA_SOURCE_REGISTRY_CONFIG')),
348
+ __metadata("design:paramtypes", [Object])
349
+ ], DataSourceRegistryService);
@@ -0,0 +1,44 @@
1
+ import { DataSource, QueryRunner } from 'typeorm';
2
+ /**
3
+ * 数据库类型
4
+ */
5
+ export type DatabaseType = 'mysql' | 'mariadb' | 'postgres' | 'cockroachdb' | 'sqlite' | 'better-sqlite3' | 'mssql' | 'oracle' | 'mongodb' | 'cordova' | 'react-native' | 'nativescript' | 'sqljs' | 'expo' | 'capacitor';
6
+ /**
7
+ * 数据库适配器
8
+ * 处理不同数据库的 SQL 语法差异
9
+ */
10
+ export declare class DatabaseAdapter {
11
+ /**
12
+ * 获取数据库类型
13
+ */
14
+ static getDatabaseType(dataSource: DataSource): DatabaseType;
15
+ /**
16
+ * 检查数据库是否支持 SAVEPOINT
17
+ */
18
+ static supportsSavepoint(dataSource: DataSource): boolean;
19
+ /**
20
+ * 创建保存点
21
+ */
22
+ static createSavepoint(queryRunner: QueryRunner, savepointName: string): Promise<void>;
23
+ /**
24
+ * 回滚到保存点
25
+ */
26
+ static rollbackToSavepoint(queryRunner: QueryRunner, savepointName: string): Promise<void>;
27
+ /**
28
+ * 释放保存点
29
+ */
30
+ static releaseSavepoint(queryRunner: QueryRunner, savepointName: string): Promise<void>;
31
+ /**
32
+ * 执行健康检查查询
33
+ */
34
+ static healthCheck(dataSource: DataSource): Promise<boolean>;
35
+ /**
36
+ * 获取数据库特定的信息
37
+ */
38
+ static getDatabaseInfo(dataSource: DataSource): {
39
+ type: DatabaseType;
40
+ supportsSavepoint: boolean;
41
+ supportsNestedTransactions: boolean;
42
+ requiresReleaseSavepoint: boolean;
43
+ };
44
+ }