@nest-omni/core 4.1.3-19 → 4.1.3-20

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 (45) hide show
  1. package/cache/cache.module.d.ts +0 -6
  2. package/cache/cache.module.js +7 -7
  3. package/cache/cache.service.js +12 -0
  4. package/cache/dependencies/db.dependency.d.ts +0 -13
  5. package/cache/dependencies/db.dependency.js +0 -16
  6. package/cache/dependencies/tag.dependency.d.ts +39 -4
  7. package/cache/dependencies/tag.dependency.js +109 -11
  8. package/cache/interfaces/cache-options.interface.d.ts +8 -0
  9. package/cache/providers/memory-cache.provider.d.ts +20 -0
  10. package/cache/providers/memory-cache.provider.js +40 -0
  11. package/http-client/config/http-client.config.d.ts +5 -0
  12. package/http-client/config/http-client.config.js +24 -13
  13. package/http-client/decorators/http-client.decorators.d.ts +1 -25
  14. package/http-client/decorators/http-client.decorators.js +97 -90
  15. package/http-client/entities/http-log.entity.d.ts +0 -20
  16. package/http-client/entities/http-log.entity.js +0 -12
  17. package/http-client/examples/advanced-usage.example.d.ts +4 -5
  18. package/http-client/examples/advanced-usage.example.js +4 -56
  19. package/http-client/http-client.module.d.ts +35 -2
  20. package/http-client/http-client.module.js +80 -75
  21. package/http-client/index.d.ts +1 -1
  22. package/http-client/interfaces/api-client-config.interface.d.ts +1 -91
  23. package/http-client/interfaces/http-client-config.interface.d.ts +53 -62
  24. package/http-client/services/api-client-registry.service.d.ts +5 -23
  25. package/http-client/services/api-client-registry.service.js +41 -284
  26. package/http-client/services/circuit-breaker.service.d.ts +69 -2
  27. package/http-client/services/circuit-breaker.service.js +185 -7
  28. package/http-client/services/http-client.service.d.ts +58 -23
  29. package/http-client/services/http-client.service.js +294 -150
  30. package/http-client/services/http-log-query.service.js +0 -13
  31. package/http-client/services/index.d.ts +0 -1
  32. package/http-client/services/index.js +0 -1
  33. package/http-client/services/logging.service.d.ts +79 -10
  34. package/http-client/services/logging.service.js +246 -51
  35. package/http-client/utils/call-stack-extractor.util.d.ts +26 -0
  36. package/http-client/utils/call-stack-extractor.util.js +35 -0
  37. package/http-client/utils/security-validator.util.d.ts +118 -0
  38. package/http-client/utils/security-validator.util.js +352 -0
  39. package/package.json +1 -1
  40. package/redis-lock/lock-heartbeat.service.d.ts +2 -0
  41. package/redis-lock/lock-heartbeat.service.js +12 -2
  42. package/redis-lock/redis-lock.service.d.ts +4 -0
  43. package/redis-lock/redis-lock.service.js +61 -8
  44. package/http-client/services/cache.service.d.ts +0 -76
  45. package/http-client/services/cache.service.js +0 -333
@@ -21,49 +21,73 @@ const common_1 = require("@nestjs/common");
21
21
  const config_1 = require("@nestjs/config");
22
22
  const typeorm_1 = require("@nestjs/typeorm");
23
23
  const typeorm_2 = require("typeorm");
24
- const cache_service_1 = require("../cache/cache.service");
25
24
  const http_client_service_1 = require("./services/http-client.service");
26
25
  const circuit_breaker_service_1 = require("./services/circuit-breaker.service");
27
26
  const logging_service_1 = require("./services/logging.service");
28
- const cache_service_2 = require("./services/cache.service");
29
27
  const http_log_query_service_1 = require("./services/http-log-query.service");
30
28
  const log_cleanup_service_1 = require("./services/log-cleanup.service");
31
29
  const api_client_registry_service_1 = require("./services/api-client-registry.service");
32
30
  const entities_1 = require("./entities");
33
- const cache_options_interface_1 = require("../cache/interfaces/cache-options.interface");
34
31
  const redis_lock_service_1 = require("../redis-lock/redis-lock.service");
32
+ const http_client_config_1 = require("./config/http-client.config");
35
33
  /**
36
34
  * HTTP客户端模块
37
35
  * 类似Spring Boot的自动配置机制,集成现有的cache服务
36
+ *
37
+ * @example
38
+ * // 最简单的方式 - 使用所有默认配置
39
+ * HttpClientModule.forRoot()
40
+ *
41
+ * @example
42
+ * // 只覆盖部分配置
43
+ * HttpClientModule.forRoot({
44
+ * baseURL: 'https://api.example.com',
45
+ * timeout: 5000,
46
+ * })
47
+ *
48
+ * @example
49
+ * // 深度合并配置
50
+ * HttpClientModule.forRoot({
51
+ * logging: {
52
+ * logLevel: 'debug',
53
+ * // 其他 logging 配置会使用默认值
54
+ * },
55
+ * })
38
56
  */
39
57
  let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
40
58
  /**
41
59
  * 动态注册HTTP客户端模块
60
+ * @param config 用户配置,所有字段都是可选的
61
+ * @returns DynamicModule
42
62
  */
43
63
  static forRoot(config = {}) {
44
- var _a, _b;
45
64
  // 基础服务提供者
46
65
  const baseProviders = [
47
66
  {
48
67
  provide: 'HTTP_CLIENT_CONFIG',
49
- useFactory: (configService, cacheService) => {
68
+ useFactory: (configService) => {
69
+ // 1. 获取环境配置
50
70
  const envConfig = this.loadConfigFromEnvironment(configService);
51
- return Object.assign(Object.assign({}, config), envConfig);
71
+ // 2. 根据环境获取基础默认配置
72
+ const nodeEnv = configService.get('NODE_ENV', 'development');
73
+ const environmentDefaults = (0, http_client_config_1.getHttpClientConfig)(nodeEnv);
74
+ // 3. 深度合并: 环境默认值 -> 环境变量配置 -> 用户配置
75
+ // 用户配置优先级最高,会覆盖前面的配置
76
+ return (0, http_client_config_1.mergeHttpClientConfig)((0, http_client_config_1.mergeHttpClientConfig)(envConfig, environmentDefaults), config);
52
77
  },
53
- inject: [config_1.ConfigService, cache_service_1.CacheService],
78
+ inject: [config_1.ConfigService],
54
79
  },
55
80
  circuit_breaker_service_1.HttpCircuitBreakerService,
56
81
  {
57
82
  provide: logging_service_1.HttpLoggingService,
58
- useFactory: (httpConfig, dataSource) => {
83
+ useFactory: (httpConfig) => {
59
84
  var _a, _b;
60
85
  // Check if database logging is enabled in the config
61
86
  const databaseLoggingEnabled = (_b = (_a = httpConfig === null || httpConfig === void 0 ? void 0 : httpConfig.logging) === null || _a === void 0 ? void 0 : _a.databaseLogging) === null || _b === void 0 ? void 0 : _b.enabled;
62
- return new logging_service_1.HttpLoggingService(databaseLoggingEnabled ? dataSource : undefined);
87
+ return new logging_service_1.HttpLoggingService();
63
88
  },
64
89
  inject: ['HTTP_CLIENT_CONFIG', typeorm_2.DataSource],
65
90
  },
66
- cache_service_2.HttpCacheService,
67
91
  http_log_query_service_1.HttpLogQueryService,
68
92
  {
69
93
  provide: log_cleanup_service_1.HttpLogCleanupService,
@@ -74,26 +98,23 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
74
98
  },
75
99
  {
76
100
  provide: api_client_registry_service_1.ApiClientRegistryService,
77
- useFactory: (httpClientService, circuitBreakerService, loggingService, cacheService, httpConfig) => {
78
- return new api_client_registry_service_1.ApiClientRegistryService(httpClientService, circuitBreakerService, loggingService, cacheService, {});
101
+ useFactory: (circuitBreakerService, loggingService, httpConfig) => {
102
+ return new api_client_registry_service_1.ApiClientRegistryService(circuitBreakerService, loggingService, {});
79
103
  },
80
104
  inject: [
81
- http_client_service_1.HttpClientService,
82
105
  circuit_breaker_service_1.HttpCircuitBreakerService,
83
106
  logging_service_1.HttpLoggingService,
84
- cache_service_2.HttpCacheService,
85
107
  'HTTP_CLIENT_CONFIG',
86
108
  ],
87
109
  },
88
110
  {
89
111
  provide: http_client_service_1.HttpClientService,
90
- useFactory: (circuitBreakerService, loggingService, cacheService, redisLockService, httpConfig) => {
91
- return new http_client_service_1.HttpClientService(circuitBreakerService, loggingService, cacheService, redisLockService, httpConfig);
112
+ useFactory: (circuitBreakerService, loggingService, redisLockService, httpConfig) => {
113
+ return new http_client_service_1.HttpClientService(circuitBreakerService, loggingService, redisLockService, httpConfig);
92
114
  },
93
115
  inject: [
94
116
  circuit_breaker_service_1.HttpCircuitBreakerService,
95
117
  logging_service_1.HttpLoggingService,
96
- cache_service_2.HttpCacheService,
97
118
  redis_lock_service_1.RedisLockService,
98
119
  'HTTP_CLIENT_CONFIG',
99
120
  ],
@@ -104,16 +125,16 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
104
125
  http_client_service_1.HttpClientService,
105
126
  circuit_breaker_service_1.HttpCircuitBreakerService,
106
127
  logging_service_1.HttpLoggingService,
107
- cache_service_2.HttpCacheService,
108
128
  http_log_query_service_1.HttpLogQueryService,
109
129
  log_cleanup_service_1.HttpLogCleanupService,
110
130
  api_client_registry_service_1.ApiClientRegistryService,
111
131
  ];
112
- // 动态导入
113
- const dynamicImports = [config_1.ConfigModule];
114
- if ((_b = (_a = config.logging) === null || _a === void 0 ? void 0 : _a.databaseLogging) === null || _b === void 0 ? void 0 : _b.enabled) {
115
- dynamicImports.push(typeorm_1.TypeOrmModule.forFeature([entities_1.HttpLogEntity]));
116
- }
132
+ // 动态导入 - 需要根据最终配置判断
133
+ // 由于配置是在运行时确定的,我们使用条件导入
134
+ const dynamicImports = [
135
+ config_1.ConfigModule,
136
+ typeorm_1.TypeOrmModule.forFeature([entities_1.HttpLogEntity]), // 始终导入,服务内部根据配置决定是否使用
137
+ ];
117
138
  return {
118
139
  module: HttpClientModule_1,
119
140
  imports: dynamicImports,
@@ -123,35 +144,50 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
123
144
  }
124
145
  /**
125
146
  * 异步注册HTTP客户端模块
147
+ * @param config 异步配置,所有字段都是可选的
148
+ * @returns DynamicModule
149
+ *
150
+ * @example
151
+ * HttpClientModule.forRootAsync({
152
+ * useFactory: (configService: ConfigService) => ({
153
+ * baseURL: configService.get('API_BASE_URL'),
154
+ * timeout: 5000,
155
+ * }),
156
+ * inject: [ConfigService],
157
+ * })
126
158
  */
127
159
  static forRootAsync(config) {
128
- // Determine if database logging will be enabled
129
- // We need to check if the config will enable database logging
130
- // This is a bit tricky since the config is async, so we'll inject DataSource conditionally later
131
- const httpConfig = config.useFactory ? {} : {};
132
160
  // 基础服务提供者
133
161
  const baseProviders = [
134
162
  {
135
163
  provide: 'HTTP_CLIENT_CONFIG',
136
164
  useFactory: (...args) => __awaiter(this, void 0, void 0, function* () {
165
+ // 1. 获取用户配置
137
166
  const userConfig = yield config.useFactory(...args);
138
- const envConfig = this.loadConfigFromEnvironment(args[0]);
139
- return Object.assign(Object.assign({}, userConfig), envConfig);
167
+ // 2. 获取环境配置
168
+ const configService = args[0];
169
+ const envConfig = this.loadConfigFromEnvironment(configService);
170
+ // 3. 根据环境获取基础默认配置
171
+ const nodeEnv = configService.get('NODE_ENV', 'development');
172
+ const environmentDefaults = (0, http_client_config_1.getHttpClientConfig)(nodeEnv);
173
+ // 4. 深度合并: 环境默认值 -> 环境变量配置 -> 用户配置
174
+ // 用户配置优先级最高,会覆盖前面的配置
175
+ const finalConfig = (0, http_client_config_1.mergeHttpClientConfig)((0, http_client_config_1.mergeHttpClientConfig)(envConfig, environmentDefaults), userConfig);
176
+ return finalConfig;
140
177
  }),
141
178
  inject: config.inject || [config_1.ConfigService],
142
179
  },
143
180
  circuit_breaker_service_1.HttpCircuitBreakerService,
144
181
  {
145
182
  provide: logging_service_1.HttpLoggingService,
146
- useFactory: (httpConfig, dataSource) => {
183
+ useFactory: (httpConfig) => {
147
184
  var _a, _b;
148
185
  // Check if database logging is enabled in the config
149
186
  const databaseLoggingEnabled = (_b = (_a = httpConfig === null || httpConfig === void 0 ? void 0 : httpConfig.logging) === null || _a === void 0 ? void 0 : _a.databaseLogging) === null || _b === void 0 ? void 0 : _b.enabled;
150
- return new logging_service_1.HttpLoggingService(databaseLoggingEnabled ? dataSource : undefined);
187
+ return new logging_service_1.HttpLoggingService();
151
188
  },
152
189
  inject: ['HTTP_CLIENT_CONFIG', typeorm_2.DataSource],
153
190
  },
154
- cache_service_2.HttpCacheService,
155
191
  http_log_query_service_1.HttpLogQueryService,
156
192
  {
157
193
  provide: log_cleanup_service_1.HttpLogCleanupService,
@@ -162,26 +198,23 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
162
198
  },
163
199
  {
164
200
  provide: api_client_registry_service_1.ApiClientRegistryService,
165
- useFactory: (httpClientService, circuitBreakerService, loggingService, cacheService, httpConfig) => {
166
- return new api_client_registry_service_1.ApiClientRegistryService(httpClientService, circuitBreakerService, loggingService, cacheService, {});
201
+ useFactory: (circuitBreakerService, loggingService, httpConfig) => {
202
+ return new api_client_registry_service_1.ApiClientRegistryService(circuitBreakerService, loggingService, {});
167
203
  },
168
204
  inject: [
169
- http_client_service_1.HttpClientService,
170
205
  circuit_breaker_service_1.HttpCircuitBreakerService,
171
206
  logging_service_1.HttpLoggingService,
172
- cache_service_2.HttpCacheService,
173
207
  'HTTP_CLIENT_CONFIG',
174
208
  ],
175
209
  },
176
210
  {
177
211
  provide: http_client_service_1.HttpClientService,
178
- useFactory: (circuitBreakerService, loggingService, cacheService, redisLockService, httpConfig) => {
179
- return new http_client_service_1.HttpClientService(circuitBreakerService, loggingService, cacheService, redisLockService, httpConfig);
212
+ useFactory: (circuitBreakerService, loggingService, redisLockService, httpConfig) => {
213
+ return new http_client_service_1.HttpClientService(circuitBreakerService, loggingService, redisLockService, httpConfig);
180
214
  },
181
215
  inject: [
182
216
  circuit_breaker_service_1.HttpCircuitBreakerService,
183
217
  logging_service_1.HttpLoggingService,
184
- cache_service_2.HttpCacheService,
185
218
  redis_lock_service_1.RedisLockService,
186
219
  'HTTP_CLIENT_CONFIG',
187
220
  ],
@@ -192,13 +225,16 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
192
225
  http_client_service_1.HttpClientService,
193
226
  circuit_breaker_service_1.HttpCircuitBreakerService,
194
227
  logging_service_1.HttpLoggingService,
195
- cache_service_2.HttpCacheService,
196
228
  http_log_query_service_1.HttpLogQueryService,
197
229
  log_cleanup_service_1.HttpLogCleanupService,
198
230
  api_client_registry_service_1.ApiClientRegistryService,
199
231
  ];
200
232
  // 动态导入
201
- const dynamicImports = [config_1.ConfigModule, ...(config.imports || [])];
233
+ const dynamicImports = [
234
+ config_1.ConfigModule,
235
+ typeorm_1.TypeOrmModule.forFeature([entities_1.HttpLogEntity]), // 始终导入,服务内部根据配置决定是否使用
236
+ ...(config.imports || []),
237
+ ];
202
238
  return {
203
239
  module: HttpClientModule_1,
204
240
  imports: dynamicImports,
@@ -210,7 +246,7 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
210
246
  * 从环境变量加载配置
211
247
  */
212
248
  static loadConfigFromEnvironment(configService) {
213
- var _a, _b, _c, _d, _e, _f, _g;
249
+ var _a;
214
250
  return {
215
251
  baseURL: configService.get('HTTP_CLIENT_BASE_URL'),
216
252
  timeout: configService.get('HTTP_CLIENT_TIMEOUT')
@@ -249,35 +285,6 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
249
285
  : 10,
250
286
  countHalfOpenCalls: configService.get('HTTP_CLIENT_CIRCUIT_BREAKER_COUNT_HALF_OPEN') === 'true',
251
287
  },
252
- cache: {
253
- enabled: configService.get('HTTP_CLIENT_CACHE_ENABLED') !== 'false',
254
- defaultTtl: configService.get('HTTP_CLIENT_CACHE_DEFAULT_TTL')
255
- ? parseInt(configService.get('HTTP_CLIENT_CACHE_DEFAULT_TTL'))
256
- : 300000,
257
- cacheableMethods: ((_b = (_a = configService
258
- .get('HTTP_CLIENT_CACHEABLE_METHODS')) === null || _a === void 0 ? void 0 : _a.split(',')) === null || _b === void 0 ? void 0 : _b.map((method) => method.trim().toUpperCase())) || [
259
- 'GET',
260
- 'HEAD',
261
- ],
262
- cacheableStatusCodes: ((_d = (_c = configService
263
- .get('HTTP_CLIENT_CACHEABLE_STATUS_CODES')) === null || _c === void 0 ? void 0 : _c.split(',')) === null || _d === void 0 ? void 0 : _d.map((code) => parseInt(code.trim()))) || [200, 201, 304],
264
- options: {
265
- layers: ((_f = (_e = configService
266
- .get('HTTP_CLIENT_CACHE_LAYERS')) === null || _e === void 0 ? void 0 : _e.split(',')) === null || _f === void 0 ? void 0 : _f.map((layer) => {
267
- const trimmed = layer.trim();
268
- switch (trimmed) {
269
- case 'cls':
270
- return cache_options_interface_1.CacheLayer.CLS;
271
- case 'memory':
272
- return cache_options_interface_1.CacheLayer.MEMORY;
273
- case 'redis':
274
- return cache_options_interface_1.CacheLayer.REDIS;
275
- default:
276
- return cache_options_interface_1.CacheLayer.MEMORY;
277
- }
278
- })) || [cache_options_interface_1.CacheLayer.MEMORY],
279
- },
280
- },
281
288
  logging: {
282
289
  enabled: configService.get('HTTP_CLIENT_LOGGING_ENABLED') !== 'false',
283
290
  logRequests: configService.get('HTTP_CLIENT_LOG_REQUESTS') !== 'false',
@@ -288,16 +295,14 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
288
295
  maxBodyLength: configService.get('HTTP_CLIENT_LOG_MAX_BODY_LENGTH')
289
296
  ? parseInt(configService.get('HTTP_CLIENT_LOG_MAX_BODY_LENGTH'))
290
297
  : undefined,
291
- sanitizeHeaders: (_g = configService
292
- .get('HTTP_CLIENT_LOG_SANITIZE_HEADERS')) === null || _g === void 0 ? void 0 : _g.split(','),
298
+ sanitizeHeaders: (_a = configService
299
+ .get('HTTP_CLIENT_LOG_SANITIZE_HEADERS')) === null || _a === void 0 ? void 0 : _a.split(','),
293
300
  logLevel: configService.get('HTTP_CLIENT_LOG_LEVEL'),
294
301
  databaseLogging: {
295
302
  enabled: configService.get('HTTP_CLIENT_DB_LOGGING_ENABLED') ===
296
303
  'true',
297
304
  dataSource: configService.get('HTTP_CLIENT_DB_LOGGING_DATA_SOURCE') ||
298
305
  'default',
299
- tableName: configService.get('HTTP_CLIENT_DB_LOGGING_TABLE_NAME') ||
300
- 'http_logs',
301
306
  },
302
307
  },
303
308
  proxy: {
@@ -1,4 +1,4 @@
1
- export { HttpClientConfig, RetryConfig, CircuitBreakerConfig, HttpCacheConfig, ProxyConfig, LoggingConfig, InterceptorConfig, ConnectionPoolConfig, HttpContext, HttpInterceptor, HttpMethod, HttpStats, } from './interfaces/http-client-config.interface';
1
+ export { HttpClientConfig, RetryConfig, CircuitBreakerConfig, ProxyConfig, LoggingConfig, InterceptorConfig, ConnectionPoolConfig, HttpContext, HttpInterceptor, HttpMethod, HttpStats, } from './interfaces/http-client-config.interface';
2
2
  export * from './interfaces/api-client-config.interface';
3
3
  export { HttpLogEntity, RetryRecord } from './entities';
4
4
  export * from './decorators';
@@ -47,6 +47,7 @@ export interface OAuth2Config {
47
47
  password?: string;
48
48
  redirectUri?: string;
49
49
  refreshToken?: string;
50
+ accessToken?: string;
50
51
  }
51
52
  /**
52
53
  * 自定义鉴权配置
@@ -184,94 +185,3 @@ export interface ApiClientRegistryConfig {
184
185
  /** 是否启用熔断器 */
185
186
  enableCircuitBreaker?: boolean;
186
187
  }
187
- /**
188
- * API客户端工厂接口
189
- */
190
- export interface ApiClientFactory {
191
- /**
192
- * 创建API客户端实例
193
- */
194
- createClient<T = any>(config: ApiClientInstanceConfig): T;
195
- /**
196
- * 获取已注册的客户端
197
- */
198
- getClient<T = any>(name: string): T;
199
- /**
200
- * 列出所有已注册的客户端
201
- */
202
- listClients(): string[];
203
- /**
204
- * 更新客户端配置
205
- */
206
- updateClient(name: string, config: Partial<ApiClientConfig>): void;
207
- /**
208
- * 移除客户端
209
- */
210
- removeClient(name: string): void;
211
- }
212
- /**
213
- * API客户端接口
214
- */
215
- export interface ApiClient {
216
- /** 客户端名称 */
217
- name: string;
218
- /** 客户端配置 */
219
- config: ApiClientConfig;
220
- /** 基础HTTP请求方法 */
221
- get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
222
- post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
223
- put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
224
- patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
225
- delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
226
- /** 通用请求方法 */
227
- request<T = any>(config: AxiosRequestConfig): Promise<T>;
228
- /** 获取客户端统计信息 */
229
- getStats(): any;
230
- /** 重置统计信息 */
231
- resetStats(): void;
232
- }
233
- /**
234
- * 通用API响应格式
235
- */
236
- export interface ApiResponse<T = any> {
237
- /** 响应数据 */
238
- data?: T;
239
- /** 响应代码 */
240
- code?: number;
241
- /** 响应消息 */
242
- message?: string;
243
- /** 成功标识 */
244
- success?: boolean;
245
- /** 错误详情 */
246
- error?: {
247
- code?: string;
248
- message?: string;
249
- details?: any;
250
- };
251
- /** 分页信息 */
252
- pagination?: {
253
- page?: number;
254
- pageSize?: number;
255
- total?: number;
256
- totalPages?: number;
257
- };
258
- /** 请求ID */
259
- requestId?: string;
260
- /** 时间戳 */
261
- timestamp?: string;
262
- }
263
- /**
264
- * 错误响应格式
265
- */
266
- export interface ErrorResponse {
267
- /** 错误代码 */
268
- code: string | number;
269
- /** 错误消息 */
270
- message: string;
271
- /** 错误详情 */
272
- details?: any;
273
- /** 堆栈信息 */
274
- stack?: string;
275
- /** 请求ID */
276
- requestId?: string;
277
- }
@@ -1,37 +1,46 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
- import { CacheOptions } from '../../cache/interfaces/cache-options.interface';
3
2
  import { LogCleanupConfig } from '../services/log-cleanup.service';
3
+ import { SSRFProtectionConfig, URLValidationConfig } from '../utils/security-validator.util';
4
4
  /**
5
5
  * HTTP客户端配置接口
6
6
  * 基于Spring Boot的@ConfigurationProperties设计理念
7
+ * 所有字段都是可选的,模块会使用合理的默认值
7
8
  */
8
9
  export interface HttpClientConfig {
9
10
  /** 基础配置 */
10
11
  baseURL?: string;
11
12
  timeout?: number;
12
13
  /** 重试配置 */
13
- retry?: RetryConfig;
14
+ retry?: Partial<RetryConfig>;
14
15
  /** 熔断器配置 */
15
- circuitBreaker?: CircuitBreakerConfig;
16
- /** 缓存配置 */
17
- cache?: HttpCacheConfig;
16
+ circuitBreaker?: Partial<CircuitBreakerConfig>;
18
17
  /** 代理配置 */
19
- proxy?: ProxyConfig;
18
+ proxy?: Partial<ProxyConfig>;
20
19
  /** 日志配置 */
21
- logging?: LoggingConfig;
20
+ logging?: Partial<LoggingConfig>;
22
21
  /** 日志清理配置 */
23
- logCleanup?: LogCleanupConfig;
22
+ logCleanup?: Partial<LogCleanupConfig>;
24
23
  /** 拦截器配置 */
25
- interceptors?: InterceptorConfig;
24
+ interceptors?: Partial<InterceptorConfig>;
26
25
  /** 连接池配置 */
27
- connectionPool?: ConnectionPoolConfig;
26
+ connectionPool?: Partial<ConnectionPoolConfig>;
27
+ /** 安全配置 */
28
+ security?: {
29
+ /** URL验证配置 */
30
+ urlValidation?: Partial<URLValidationConfig>;
31
+ /** SSRF防护配置 */
32
+ ssrfProtection?: Partial<SSRFProtectionConfig>;
33
+ /** 是否启用安全验证 */
34
+ enabled?: boolean;
35
+ };
28
36
  }
29
37
  /**
30
38
  * 重试配置
31
39
  * 基于axios-retry库的配置
40
+ * 所有字段都是可选的
32
41
  */
33
42
  export interface RetryConfig {
34
- enabled: boolean;
43
+ enabled?: boolean;
35
44
  retries?: number;
36
45
  retryDelay?: (retryCount: number) => number;
37
46
  retryCondition?: (error: any) => boolean;
@@ -41,37 +50,22 @@ export interface RetryConfig {
41
50
  /**
42
51
  * 熔断器配置
43
52
  * 类似Spring Cloud CircuitBreaker
53
+ * 所有字段都是可选的
44
54
  */
45
55
  export interface CircuitBreakerConfig {
46
- enabled: boolean;
47
- failureThreshold: number;
48
- recoveryTimeoutMs: number;
49
- monitoringPeriodMs: number;
50
- minimumThroughputThreshold: number;
51
- countHalfOpenCalls: boolean;
52
- }
53
- /**
54
- * HTTP缓存配置
55
- * 集成现有的三层缓存架构
56
- */
57
- export interface HttpCacheConfig {
58
- enabled: boolean;
59
- /** 缓存选项,使用core中的CacheOptions */
60
- options?: Omit<CacheOptions, 'ttl' | 'namespace'>;
61
- /** 默认TTL(毫秒) */
62
- defaultTtl?: number;
63
- /** 可缓存的方法 */
64
- cacheableMethods: string[];
65
- /** 可缓存的状态码 */
66
- cacheableStatusCodes: number[];
67
- /** 自定义缓存键生成器 */
68
- keyGenerator?: (config: AxiosRequestConfig) => string;
56
+ enabled?: boolean;
57
+ failureThreshold?: number;
58
+ recoveryTimeoutMs?: number;
59
+ monitoringPeriodMs?: number;
60
+ minimumThroughputThreshold?: number;
61
+ countHalfOpenCalls?: boolean;
69
62
  }
70
63
  /**
71
64
  * 代理配置
65
+ * 所有字段都是可选的
72
66
  */
73
67
  export interface ProxyConfig {
74
- enabled: boolean;
68
+ enabled?: boolean;
75
69
  /** 是否从环境变量读取代理配置 (HTTP_PROXY, HTTPS_PROXY, NO_PROXY) */
76
70
  fromEnvironment?: boolean;
77
71
  /** 手动指定的代理主机 (当 fromEnvironment 为 false 时使用) */
@@ -82,47 +76,49 @@ export interface ProxyConfig {
82
76
  protocol?: 'http' | 'https';
83
77
  /** 代理认证信息 */
84
78
  auth?: {
85
- username: string;
86
- password: string;
79
+ username?: string;
80
+ password?: string;
87
81
  };
88
82
  }
89
83
  /**
90
84
  * 日志配置
91
85
  * 类似Spring Boot的logging配置
86
+ * 所有字段都是可选的
92
87
  */
93
88
  export interface LoggingConfig {
94
- enabled: boolean;
95
- logRequests: boolean;
96
- logResponses: boolean;
97
- logErrors: boolean;
98
- logHeaders: boolean;
99
- logBody: boolean;
100
- maxBodyLength: number;
101
- sanitizeHeaders: string[];
102
- logLevel: 'debug' | 'info' | 'warn' | 'error';
89
+ enabled?: boolean;
90
+ logRequests?: boolean;
91
+ logResponses?: boolean;
92
+ logErrors?: boolean;
93
+ logHeaders?: boolean;
94
+ logBody?: boolean;
95
+ maxBodyLength?: number;
96
+ sanitizeHeaders?: string[];
97
+ logLevel?: 'debug' | 'info' | 'warn' | 'error';
103
98
  databaseLogging?: {
104
- enabled: boolean;
105
- dataSource: string;
106
- tableName: string;
99
+ enabled?: boolean;
100
+ dataSource?: string;
107
101
  };
108
102
  }
109
103
  /**
110
104
  * 拦截器配置
105
+ * 所有字段都是可选的
111
106
  */
112
107
  export interface InterceptorConfig {
113
- requestInterceptors: string[];
114
- responseInterceptors: string[];
115
- errorInterceptors: string[];
108
+ requestInterceptors?: string[];
109
+ responseInterceptors?: string[];
110
+ errorInterceptors?: string[];
116
111
  }
117
112
  /**
118
113
  * 连接池配置
114
+ * 所有字段都是可选的
119
115
  */
120
116
  export interface ConnectionPoolConfig {
121
- enabled: boolean;
122
- maxSockets: number;
123
- maxFreeSockets: number;
124
- timeoutMs: number;
125
- keepAlive: boolean;
117
+ enabled?: boolean;
118
+ maxSockets?: number;
119
+ maxFreeSockets?: number;
120
+ timeoutMs?: number;
121
+ keepAlive?: boolean;
126
122
  }
127
123
  /**
128
124
  * HTTP请求上下文
@@ -181,9 +177,4 @@ export interface HttpStats {
181
177
  requestsByMethod: Record<HttpMethod, number>;
182
178
  requestsByStatus: Record<number, number>;
183
179
  circuitBreakerStats: Record<string, any>;
184
- cacheStats: {
185
- hits: number;
186
- misses: number;
187
- hitRate: number;
188
- };
189
180
  }
@@ -1,24 +1,22 @@
1
- import { ApiClientConfig, ApiClientInstanceConfig, ApiClientRegistryConfig, AuthType, OAuth2Config, ResponseTransformerConfig } from '../interfaces/api-client-config.interface';
2
- import { HttpClientService } from './http-client.service';
1
+ import { ApiClientConfig, ApiClientInstanceConfig, ApiClientRegistryConfig, AuthType, ResponseTransformerConfig } from '../interfaces/api-client-config.interface';
3
2
  import { HttpCircuitBreakerService } from './circuit-breaker.service';
4
3
  import { HttpLoggingService } from './logging.service';
5
- import { HttpCacheService } from './cache.service';
6
- export { ApiClientInstanceConfig, AuthType, OAuth2Config, ResponseTransformerConfig, };
4
+ export { ApiClientInstanceConfig, AuthType, ResponseTransformerConfig, };
7
5
  /**
8
6
  * API客户端注册服务
7
+ * 负责管理多个 HttpClientService 实例
9
8
  */
10
9
  export declare class ApiClientRegistryService {
11
- private readonly httpClientService;
12
10
  private readonly circuitBreakerService;
13
11
  private readonly loggingService;
14
- private readonly cacheService;
15
12
  private readonly logger;
16
13
  private readonly clients;
17
14
  private readonly clientConfigs;
18
15
  private readonly globalDefaults;
19
- constructor(httpClientService: HttpClientService, circuitBreakerService: HttpCircuitBreakerService, loggingService: HttpLoggingService, cacheService: HttpCacheService, globalConfig?: ApiClientRegistryConfig);
16
+ constructor(circuitBreakerService: HttpCircuitBreakerService, loggingService: HttpLoggingService, globalConfig?: ApiClientRegistryConfig);
20
17
  /**
21
18
  * 创建API客户端实例
19
+ * 使用 HttpClientService.createApiClient 静态方法创建
22
20
  */
23
21
  createClient<T = any>(config: ApiClientInstanceConfig): T;
24
22
  /**
@@ -75,22 +73,6 @@ export declare class ApiClientRegistryService {
75
73
  error?: string;
76
74
  }>;
77
75
  }>;
78
- /**
79
- * 创建Axios实例
80
- */
81
- private createAxiosInstance;
82
- /**
83
- * 应用鉴权配置
84
- */
85
- private applyAuthentication;
86
- /**
87
- * 应用响应转换器
88
- */
89
- private applyResponseTransformer;
90
- /**
91
- * 根据路径提取数据
92
- */
93
- private extractDataByPath;
94
76
  /**
95
77
  * 合并环境特定配置
96
78
  */