@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
@@ -1,5 +1,4 @@
1
1
  import { DynamicModule, OnModuleInit } from '@nestjs/common';
2
- import type { DataSource } from 'typeorm';
3
2
  import type { Redis } from 'ioredis';
4
3
  import { CacheService } from './cache.service';
5
4
  /**
@@ -20,11 +19,6 @@ export interface CacheModuleOptions {
20
19
  * If not provided, Redis caching will be disabled
21
20
  */
22
21
  redisClient?: Redis;
23
- /**
24
- * TypeORM DataSource for DbDependency
25
- * If not provided, DbDependency will throw error when used
26
- */
27
- dataSource?: DataSource;
28
22
  /**
29
23
  * Default TTL for memory cache in milliseconds
30
24
  */
@@ -80,10 +80,10 @@ let CacheModule = CacheModule_1 = class CacheModule {
80
80
  * Register cache module with options
81
81
  */
82
82
  static forRoot(options = {}) {
83
- const { isGlobal = true, redisClient, dataSource, memoryTtl, memoryNamespace, enableCompression = false, compressionThreshold = 1024, } = options;
84
- // Set DataSource for DbDependency if provided
85
- if (dataSource) {
86
- dependencies_1.DbDependency.setDataSource(dataSource);
83
+ const { isGlobal = true, redisClient, memoryTtl, memoryNamespace, enableCompression = false, compressionThreshold = 1024, } = options;
84
+ // Set Redis client for TagDependency for distributed tag support
85
+ if (redisClient) {
86
+ dependencies_1.TagDependency.setRedisClient(redisClient);
87
87
  }
88
88
  return {
89
89
  module: CacheModule_1,
@@ -161,9 +161,9 @@ let CacheModule = CacheModule_1 = class CacheModule {
161
161
  {
162
162
  provide: providers_1.MemoryCacheProvider,
163
163
  useFactory: (moduleOptions) => {
164
- // Set DataSource for DbDependency if provided
165
- if (moduleOptions.dataSource) {
166
- dependencies_1.DbDependency.setDataSource(moduleOptions.dataSource);
164
+ // Set Redis client for TagDependency for distributed tag support
165
+ if (moduleOptions.redisClient) {
166
+ dependencies_1.TagDependency.setRedisClient(moduleOptions.redisClient);
167
167
  }
168
168
  return new providers_1.MemoryCacheProvider({
169
169
  ttl: moduleOptions.memoryTtl,
@@ -333,6 +333,18 @@ let CacheService = CacheService_1 = class CacheService {
333
333
  setWithOptions(key, value, options) {
334
334
  return __awaiter(this, void 0, void 0, function* () {
335
335
  this.stats.totalSets++;
336
+ // Validate TTL if provided
337
+ if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
338
+ if (typeof options.ttl !== 'number' || options.ttl < 0) {
339
+ this.logger.warn(`Invalid TTL value: ${options.ttl}. TTL must be a non-negative number. Using default behavior.`);
340
+ // Continue without TTL
341
+ options.ttl = undefined;
342
+ }
343
+ else if (options.ttl === 0) {
344
+ // TTL of 0 means no expiration
345
+ options.ttl = undefined;
346
+ }
347
+ }
336
348
  // Check condition
337
349
  if ((options === null || options === void 0 ? void 0 : options.condition) && !(yield Promise.resolve(options.condition()))) {
338
350
  return;
@@ -1,4 +1,3 @@
1
- import { DataSource } from 'typeorm';
2
1
  import type { CacheDependency } from '../interfaces';
3
2
  /**
4
3
  * Options for DbDependency
@@ -77,18 +76,6 @@ export declare class DbDependency implements CacheDependency {
77
76
  private static fallbackDataSource;
78
77
  private static defaultDataSourceName;
79
78
  constructor(sql: string, paramsFactory?: (...args: any[]) => any[], options?: DbDependencyOptions);
80
- /**
81
- * Set a fallback DataSource for database queries
82
- * This is used when DataSourceUtil cannot provide a DataSource
83
- * This method is deprecated - use DataSourceUtil.registerDataSource() instead
84
- * @deprecated Use DataSourceUtil.registerDataSource() to register DataSources
85
- */
86
- static setDataSource(dataSource: DataSource): void;
87
- /**
88
- * Set the default data source name for DbDependency
89
- * @param name The data source name (default: 'default')
90
- */
91
- static setDefaultDataSourceName(name: string): void;
92
79
  /**
93
80
  * Get DataSource for executing queries
94
81
  * Priority: 1. Specific dataSourceName from options, 2. Default from getDataSourceByName, 3. Fallback
@@ -75,22 +75,6 @@ class DbDependency {
75
75
  throw new Error('DbDependency requires a valid SQL query');
76
76
  }
77
77
  }
78
- /**
79
- * Set a fallback DataSource for database queries
80
- * This is used when DataSourceUtil cannot provide a DataSource
81
- * This method is deprecated - use DataSourceUtil.registerDataSource() instead
82
- * @deprecated Use DataSourceUtil.registerDataSource() to register DataSources
83
- */
84
- static setDataSource(dataSource) {
85
- this.fallbackDataSource = dataSource;
86
- }
87
- /**
88
- * Set the default data source name for DbDependency
89
- * @param name The data source name (default: 'default')
90
- */
91
- static setDefaultDataSourceName(name) {
92
- this.defaultDataSourceName = name;
93
- }
94
78
  /**
95
79
  * Get DataSource for executing queries
96
80
  * Priority: 1. Specific dataSourceName from options, 2. Default from getDataSourceByName, 3. Fallback
@@ -1,4 +1,5 @@
1
1
  import type { CacheDependency } from '../interfaces/cache-dependency.interface';
2
+ import type Redis from 'ioredis';
2
3
  /**
3
4
  * Tag-based cache dependency
4
5
  *
@@ -7,6 +8,9 @@ import type { CacheDependency } from '../interfaces/cache-dependency.interface';
7
8
  *
8
9
  * This is the most commonly used dependency type for managing related cache entries.
9
10
  *
11
+ * **Distributed Support**: Tag versions are stored in Redis for multi-instance deployments.
12
+ * Falls back to in-memory storage if Redis is not available.
13
+ *
10
14
  * @example
11
15
  * ```typescript
12
16
  * // Cache user list with tag dependency
@@ -23,28 +27,59 @@ import type { CacheDependency } from '../interfaces/cache-dependency.interface';
23
27
  export declare class TagDependency implements CacheDependency {
24
28
  private readonly tags;
25
29
  private static readonly PREFIX;
30
+ private static readonly REDIS_KEY_PREFIX;
26
31
  private static tagVersions;
32
+ private static redis;
27
33
  constructor(tags: string[]);
34
+ /**
35
+ * Set Redis client for distributed tag version storage
36
+ * Called by CacheModule during initialization
37
+ *
38
+ * @param redis - Redis client instance
39
+ */
40
+ static setRedisClient(redis: Redis): void;
28
41
  /**
29
42
  * Get current version of a tag
43
+ * Prioritizes Redis, falls back to in-memory storage
44
+ *
45
+ * @param tag - Tag name
46
+ * @returns Current tag version
30
47
  */
31
- static getTagVersion(tag: string): number;
48
+ static getTagVersion(tag: string): Promise<number>;
32
49
  /**
33
50
  * Invalidate a tag (increment its version)
51
+ * Updates both Redis and in-memory storage
52
+ *
53
+ * @param tag - Tag name to invalidate
34
54
  */
35
- static invalidateTag(tag: string): void;
55
+ static invalidateTag(tag: string): Promise<void>;
36
56
  /**
37
57
  * Invalidate multiple tags
58
+ *
59
+ * @param tags - Array of tag names to invalidate
38
60
  */
39
- static invalidateTags(tags: string[]): void;
61
+ static invalidateTags(tags: string[]): Promise<void>;
40
62
  /**
41
63
  * Reset all tag versions (useful for testing)
64
+ * Clears both Redis and in-memory storage
42
65
  */
43
- static resetAllTags(): void;
66
+ static resetAllTags(): Promise<void>;
44
67
  /**
45
68
  * Get all tags and their versions
69
+ * Note: This only returns in-memory tags for backward compatibility
70
+ *
71
+ * @returns Map of tag names to versions
46
72
  */
47
73
  static getAllTags(): Map<string, number>;
74
+ /**
75
+ * Get tag version (synchronous version for backward compatibility)
76
+ * Only reads from in-memory storage
77
+ *
78
+ * @deprecated Use getTagVersion(tag) instead for distributed support
79
+ * @param tag - Tag name
80
+ * @returns Current tag version from memory
81
+ */
82
+ static getTagVersionSync(tag: string): number;
48
83
  getKey(): string;
49
84
  getData(): Promise<Record<string, number>>;
50
85
  isChanged(oldData: Record<string, number>): Promise<boolean>;
@@ -18,6 +18,9 @@ exports.TagDependency = void 0;
18
18
  *
19
19
  * This is the most commonly used dependency type for managing related cache entries.
20
20
  *
21
+ * **Distributed Support**: Tag versions are stored in Redis for multi-instance deployments.
22
+ * Falls back to in-memory storage if Redis is not available.
23
+ *
21
24
  * @example
22
25
  * ```typescript
23
26
  * // Cache user list with tag dependency
@@ -38,38 +41,129 @@ class TagDependency {
38
41
  throw new Error('TagDependency requires at least one tag');
39
42
  }
40
43
  }
44
+ /**
45
+ * Set Redis client for distributed tag version storage
46
+ * Called by CacheModule during initialization
47
+ *
48
+ * @param redis - Redis client instance
49
+ */
50
+ static setRedisClient(redis) {
51
+ TagDependency.redis = redis;
52
+ }
41
53
  /**
42
54
  * Get current version of a tag
55
+ * Prioritizes Redis, falls back to in-memory storage
56
+ *
57
+ * @param tag - Tag name
58
+ * @returns Current tag version
43
59
  */
44
60
  static getTagVersion(tag) {
45
- return this.tagVersions.get(tag) || 0;
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ // Try to get from Redis first
63
+ if (TagDependency.redis) {
64
+ try {
65
+ const key = `${TagDependency.REDIS_KEY_PREFIX}:${tag}`;
66
+ const result = yield TagDependency.redis.get(key);
67
+ if (result !== null) {
68
+ const version = parseInt(result, 10);
69
+ // Cache in memory for faster access
70
+ TagDependency.tagVersions.set(tag, version);
71
+ return version;
72
+ }
73
+ }
74
+ catch (error) {
75
+ // Log warning but don't throw - fall back to memory
76
+ console.warn(`[TagDependency] Failed to get tag version from Redis: ${error instanceof Error ? error.message : String(error)}`);
77
+ }
78
+ }
79
+ // Fall back to in-memory storage
80
+ return TagDependency.tagVersions.get(tag) || 0;
81
+ });
46
82
  }
47
83
  /**
48
84
  * Invalidate a tag (increment its version)
85
+ * Updates both Redis and in-memory storage
86
+ *
87
+ * @param tag - Tag name to invalidate
49
88
  */
50
89
  static invalidateTag(tag) {
51
- const currentVersion = this.tagVersions.get(tag) || 0;
52
- this.tagVersions.set(tag, currentVersion + 1);
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ const currentVersion = TagDependency.tagVersions.get(tag) || 0;
92
+ const newVersion = currentVersion + 1;
93
+ // Update in-memory storage
94
+ TagDependency.tagVersions.set(tag, newVersion);
95
+ // Update Redis if available
96
+ if (TagDependency.redis) {
97
+ try {
98
+ const key = `${TagDependency.REDIS_KEY_PREFIX}:${tag}`;
99
+ yield TagDependency.redis.set(key, newVersion.toString());
100
+ }
101
+ catch (error) {
102
+ console.error(`[TagDependency] Failed to invalidate tag in Redis: ${error instanceof Error ? error.message : String(error)}`);
103
+ }
104
+ }
105
+ });
53
106
  }
54
107
  /**
55
108
  * Invalidate multiple tags
109
+ *
110
+ * @param tags - Array of tag names to invalidate
56
111
  */
57
112
  static invalidateTags(tags) {
58
- for (const tag of tags) {
59
- this.invalidateTag(tag);
60
- }
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ yield Promise.all(tags.map((tag) => TagDependency.invalidateTag(tag)));
115
+ });
61
116
  }
62
117
  /**
63
118
  * Reset all tag versions (useful for testing)
119
+ * Clears both Redis and in-memory storage
64
120
  */
65
121
  static resetAllTags() {
66
- this.tagVersions.clear();
122
+ return __awaiter(this, void 0, void 0, function* () {
123
+ // Clear in-memory storage
124
+ TagDependency.tagVersions.clear();
125
+ // Clear Redis storage
126
+ if (TagDependency.redis) {
127
+ try {
128
+ let cursor = '0';
129
+ const pattern = `${TagDependency.REDIS_KEY_PREFIX}:*`;
130
+ const keysToDelete = [];
131
+ // Use SCAN to find all tag version keys
132
+ do {
133
+ const [nextCursor, keys] = yield TagDependency.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
134
+ cursor = nextCursor;
135
+ keysToDelete.push(...keys);
136
+ } while (cursor !== '0');
137
+ // Delete all found keys
138
+ if (keysToDelete.length > 0) {
139
+ yield TagDependency.redis.del(...keysToDelete);
140
+ }
141
+ }
142
+ catch (error) {
143
+ console.error(`[TagDependency] Failed to reset tags in Redis: ${error instanceof Error ? error.message : String(error)}`);
144
+ }
145
+ }
146
+ });
67
147
  }
68
148
  /**
69
149
  * Get all tags and their versions
150
+ * Note: This only returns in-memory tags for backward compatibility
151
+ *
152
+ * @returns Map of tag names to versions
70
153
  */
71
154
  static getAllTags() {
72
- return new Map(this.tagVersions);
155
+ return new Map(TagDependency.tagVersions);
156
+ }
157
+ /**
158
+ * Get tag version (synchronous version for backward compatibility)
159
+ * Only reads from in-memory storage
160
+ *
161
+ * @deprecated Use getTagVersion(tag) instead for distributed support
162
+ * @param tag - Tag name
163
+ * @returns Current tag version from memory
164
+ */
165
+ static getTagVersionSync(tag) {
166
+ return TagDependency.tagVersions.get(tag) || 0;
73
167
  }
74
168
  getKey() {
75
169
  return `tag:${this.tags.sort().join(',')}`;
@@ -78,7 +172,7 @@ class TagDependency {
78
172
  return __awaiter(this, void 0, void 0, function* () {
79
173
  const data = {};
80
174
  for (const tag of this.tags) {
81
- data[tag] = TagDependency.getTagVersion(tag);
175
+ data[tag] = yield TagDependency.getTagVersion(tag);
82
176
  }
83
177
  return data;
84
178
  });
@@ -89,7 +183,7 @@ class TagDependency {
89
183
  return true;
90
184
  }
91
185
  for (const tag of this.tags) {
92
- const currentVersion = TagDependency.getTagVersion(tag);
186
+ const currentVersion = yield TagDependency.getTagVersion(tag);
93
187
  const oldVersion = oldData[tag];
94
188
  if (currentVersion !== oldVersion) {
95
189
  return true;
@@ -101,11 +195,15 @@ class TagDependency {
101
195
  reset() {
102
196
  return __awaiter(this, void 0, void 0, function* () {
103
197
  for (const tag of this.tags) {
104
- TagDependency.invalidateTag(tag);
198
+ yield TagDependency.invalidateTag(tag);
105
199
  }
106
200
  });
107
201
  }
108
202
  }
109
203
  exports.TagDependency = TagDependency;
110
204
  TagDependency.PREFIX = 'cache:tag:';
205
+ TagDependency.REDIS_KEY_PREFIX = 'cache:tag:versions';
206
+ // In-memory fallback for when Redis is not available
111
207
  TagDependency.tagVersions = new Map();
208
+ // Redis client for distributed tag version storage
209
+ TagDependency.redis = null;
@@ -35,6 +35,14 @@ export interface CacheOptions {
35
35
  * @returns true to cache, false to skip
36
36
  */
37
37
  condition?: (...args: any[]) => boolean | Promise<boolean>;
38
+ /**
39
+ * Unless condition - skip caching when this condition is true
40
+ * Can be a function (safe) or a string expression (use with caution)
41
+ * @param result - Method return value
42
+ * @param args - Method arguments
43
+ * @returns true to skip caching, false to cache normally
44
+ */
45
+ unless?: ((result: any, args: any[]) => boolean) | string;
38
46
  /**
39
47
  * Cache dependencies - cache will be invalidated when dependencies change
40
48
  * Similar to Yii2 cache dependency system
@@ -6,16 +6,36 @@ import { BaseCacheProvider } from './base-cache.provider';
6
6
  * Data is stored in memory and shared across all requests in the same process.
7
7
  *
8
8
  * Faster than Redis but not shared across multiple processes/servers.
9
+ *
10
+ * **Automatic Cleanup**: Includes periodic cleanup of expired items to prevent memory leaks.
9
11
  */
10
12
  export declare class MemoryCacheProvider extends BaseCacheProvider {
11
13
  private cache;
12
14
  private keys;
13
15
  private defaultTtl?;
14
16
  private namespace;
17
+ private cleanupTimer?;
18
+ /**
19
+ * Cleanup interval in milliseconds
20
+ * @default 300000 (5 minutes)
21
+ */
22
+ private readonly CLEANUP_INTERVAL;
15
23
  constructor(options?: {
16
24
  ttl?: number;
17
25
  namespace?: string;
18
26
  });
27
+ /**
28
+ * Start periodic cleanup of expired items
29
+ */
30
+ private startCleanupTimer;
31
+ /**
32
+ * Stop automatic cleanup timer
33
+ */
34
+ private stopCleanupTimer;
35
+ /**
36
+ * Destroy the provider and cleanup resources
37
+ */
38
+ destroy(): void;
19
39
  getName(): string;
20
40
  get<T>(key: string): Promise<T | null>;
21
41
  set<T>(key: string, value: T, ttl?: number): Promise<void>;
@@ -18,14 +18,54 @@ const base_cache_provider_1 = require("./base-cache.provider");
18
18
  * Data is stored in memory and shared across all requests in the same process.
19
19
  *
20
20
  * Faster than Redis but not shared across multiple processes/servers.
21
+ *
22
+ * **Automatic Cleanup**: Includes periodic cleanup of expired items to prevent memory leaks.
21
23
  */
22
24
  class MemoryCacheProvider extends base_cache_provider_1.BaseCacheProvider {
23
25
  constructor(options) {
24
26
  super();
25
27
  this.cache = new Map();
26
28
  this.keys = new Set();
29
+ /**
30
+ * Cleanup interval in milliseconds
31
+ * @default 300000 (5 minutes)
32
+ */
33
+ this.CLEANUP_INTERVAL = 5 * 60 * 1000;
27
34
  this.defaultTtl = options === null || options === void 0 ? void 0 : options.ttl;
28
35
  this.namespace = (options === null || options === void 0 ? void 0 : options.namespace) || 'cache:memory';
36
+ // Start automatic cleanup timer
37
+ this.startCleanupTimer();
38
+ }
39
+ /**
40
+ * Start periodic cleanup of expired items
41
+ */
42
+ startCleanupTimer() {
43
+ this.cleanupTimer = setInterval(() => {
44
+ const cleaned = this.cleanup();
45
+ if (cleaned > 0) {
46
+ console.debug(`[MemoryCache] Cleaned up ${cleaned} expired items from namespace: ${this.namespace}`);
47
+ }
48
+ }, this.CLEANUP_INTERVAL);
49
+ // Allow Node.js to exit if this is the only active timer
50
+ if (this.cleanupTimer.unref) {
51
+ this.cleanupTimer.unref();
52
+ }
53
+ }
54
+ /**
55
+ * Stop automatic cleanup timer
56
+ */
57
+ stopCleanupTimer() {
58
+ if (this.cleanupTimer) {
59
+ clearInterval(this.cleanupTimer);
60
+ this.cleanupTimer = undefined;
61
+ }
62
+ }
63
+ /**
64
+ * Destroy the provider and cleanup resources
65
+ */
66
+ destroy() {
67
+ this.stopCleanupTimer();
68
+ this.clear();
29
69
  }
30
70
  getName() {
31
71
  return 'Memory';
@@ -1,4 +1,9 @@
1
1
  import { HttpClientConfig } from '../interfaces/http-client-config.interface';
2
+ /**
3
+ * 深度合并配置
4
+ * 将用户配置与默认配置合并,用户配置会覆盖默认配置
5
+ */
6
+ export declare function mergeHttpClientConfig(userConfig?: Partial<HttpClientConfig>, defaultConfig?: Partial<HttpClientConfig>): HttpClientConfig;
2
7
  /**
3
8
  * HTTP客户端默认配置
4
9
  */
@@ -1,8 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TEST_HTTP_CLIENT_CONFIG = exports.PRODUCTION_HTTP_CLIENT_CONFIG = exports.DEVELOPMENT_HTTP_CLIENT_CONFIG = exports.DEFAULT_HTTP_CLIENT_CONFIG = void 0;
4
+ exports.mergeHttpClientConfig = mergeHttpClientConfig;
4
5
  exports.getHttpClientConfig = getHttpClientConfig;
5
- const cache_options_interface_1 = require("../../cache/interfaces/cache-options.interface");
6
+ /**
7
+ * 深度合并对象
8
+ * 用于合并用户配置和默认配置
9
+ */
10
+ function deepMerge(target, source) {
11
+ const result = Object.assign({}, target);
12
+ for (const key in source) {
13
+ if (source[key] instanceof Object && key in target && !Array.isArray(source[key])) {
14
+ result[key] = deepMerge(target[key], source[key]);
15
+ }
16
+ else {
17
+ result[key] = source[key];
18
+ }
19
+ }
20
+ return result;
21
+ }
22
+ /**
23
+ * 深度合并配置
24
+ * 将用户配置与默认配置合并,用户配置会覆盖默认配置
25
+ */
26
+ function mergeHttpClientConfig(userConfig = {}, defaultConfig = exports.DEFAULT_HTTP_CLIENT_CONFIG) {
27
+ return deepMerge(defaultConfig, userConfig);
28
+ }
6
29
  /**
7
30
  * HTTP客户端默认配置
8
31
  */
@@ -29,15 +52,6 @@ exports.DEFAULT_HTTP_CLIENT_CONFIG = {
29
52
  minimumThroughputThreshold: 10,
30
53
  countHalfOpenCalls: false,
31
54
  },
32
- cache: {
33
- enabled: true,
34
- defaultTtl: 300000, // 5分钟
35
- cacheableMethods: ['GET', 'HEAD'],
36
- cacheableStatusCodes: [200, 201, 304],
37
- options: {
38
- layers: [cache_options_interface_1.CacheLayer.CLS, cache_options_interface_1.CacheLayer.MEMORY, cache_options_interface_1.CacheLayer.REDIS],
39
- },
40
- },
41
55
  logging: {
42
56
  enabled: true,
43
57
  logRequests: true,
@@ -51,7 +65,6 @@ exports.DEFAULT_HTTP_CLIENT_CONFIG = {
51
65
  databaseLogging: {
52
66
  enabled: false, // 默认不启用数据库日志
53
67
  dataSource: 'default',
54
- tableName: 'http_logs',
55
68
  },
56
69
  },
57
70
  logCleanup: {
@@ -69,7 +82,6 @@ exports.DEFAULT_HTTP_CLIENT_CONFIG = {
69
82
  exports.DEVELOPMENT_HTTP_CLIENT_CONFIG = Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG), { logging: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.logging), { enabled: true, logHeaders: true, logBody: true, logLevel: 'debug', databaseLogging: {
70
83
  enabled: true, // 开发环境启用数据库日志
71
84
  dataSource: 'default',
72
- tableName: 'http_logs',
73
85
  } }), logCleanup: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.logCleanup), { enabled: false }) });
74
86
  /**
75
87
  * 生产环境配置
@@ -77,7 +89,6 @@ exports.DEVELOPMENT_HTTP_CLIENT_CONFIG = Object.assign(Object.assign({}, exports
77
89
  exports.PRODUCTION_HTTP_CLIENT_CONFIG = Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG), { timeout: 60000, retry: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.retry), { retries: 5 }), circuitBreaker: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.circuitBreaker), { failureThreshold: 3, recoveryTimeoutMs: 120000 }), logging: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.logging), { enabled: true, logHeaders: false, logBody: false, logLevel: 'warn', databaseLogging: {
78
90
  enabled: true, // 生产环境启用数据库日志
79
91
  dataSource: 'default',
80
- tableName: 'http_logs',
81
92
  } }), logCleanup: Object.assign(Object.assign({}, exports.DEFAULT_HTTP_CLIENT_CONFIG.logCleanup), { enabled: true, retentionDays: 7, maxRecords: 50000, schedule: '0 3 * * *' }) });
82
93
  /**
83
94
  * 测试环境配置
@@ -1,9 +1,8 @@
1
1
  import 'reflect-metadata';
2
- import { CircuitBreakerConfig, HttpCacheConfig, HttpClientConfig, RetryConfig } from '../interfaces/http-client-config.interface';
2
+ import { CircuitBreakerConfig, HttpClientConfig, RetryConfig } from '../interfaces/http-client-config.interface';
3
3
  export declare const HTTP_CLIENT_OPTIONS_KEY = "http_client_options";
4
4
  export declare const RETRY_OPTIONS_KEY = "http_retry_options";
5
5
  export declare const CIRCUIT_BREAKER_OPTIONS_KEY = "http_circuit_breaker_options";
6
- export declare const CACHE_OPTIONS_KEY = "http_cache_options";
7
6
  export declare const LOGGING_OPTIONS_KEY = "http_logging_options";
8
7
  export declare const TIMEOUT_OPTIONS_KEY = "http_timeout_options";
9
8
  export declare const PROXY_OPTIONS_KEY = "http_proxy_options";
@@ -34,24 +33,6 @@ export declare const HttpCircuitBreaker: (options?: {
34
33
  monitoringPeriodMs?: number;
35
34
  minimumThroughputThreshold?: number;
36
35
  }) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
37
- /**
38
- * HTTP缓存装饰器
39
- * 集成现有的三层缓存架构
40
- */
41
- export declare const HttpCacheable: (options?: {
42
- /** 缓存TTL(毫秒) */
43
- ttl?: number;
44
- /** 缓存键 */
45
- key?: string | ((...args: any[]) => string);
46
- /** 缓存层 */
47
- layers?: Array<"cls" | "memory" | "redis">;
48
- /** 缓存条件 */
49
- condition?: (...args: any[]) => boolean | Promise<boolean>;
50
- /** 除非条件 */
51
- unless?: string | ((result: any, args: any[]) => boolean);
52
- /** 命名空间 */
53
- namespace?: string;
54
- }) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
55
36
  /**
56
37
  * 请求日志装饰器
57
38
  * 类似Spring Boot的@LogRequest注解
@@ -97,10 +78,6 @@ export declare class HttpDecoratorUtils {
97
78
  * 获取方法上的熔断器配置
98
79
  */
99
80
  static getCircuitBreakerOptions(target: any, propertyKey: string): CircuitBreakerConfig | undefined;
100
- /**
101
- * 获取方法上的缓存配置
102
- */
103
- static getCacheOptions(target: any, propertyKey: string): HttpCacheConfig | undefined;
104
81
  /**
105
82
  * 获取方法上的日志配置
106
83
  */
@@ -127,7 +104,6 @@ export declare class HttpDecoratorUtils {
127
104
  static getAllDecoratorConfigs(target: any, propertyKey: string): {
128
105
  retry?: RetryConfig;
129
106
  circuitBreaker?: CircuitBreakerConfig;
130
- cache?: HttpCacheConfig;
131
107
  logging?: any;
132
108
  timeout?: number;
133
109
  proxy?: any;