@nest-omni/core 4.1.3-25 → 4.1.3-27

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 (48) hide show
  1. package/cache/cache.service.d.ts +3 -1
  2. package/cache/cache.service.js +8 -8
  3. package/cache/decorators/cache-put.decorator.js +5 -4
  4. package/cache/dependencies/callback.dependency.js +9 -0
  5. package/cache/dependencies/tag.dependency.d.ts +1 -9
  6. package/cache/dependencies/tag.dependency.js +5 -14
  7. package/cache/providers/lrucache.provider.d.ts +1 -0
  8. package/cache/providers/lrucache.provider.js +6 -4
  9. package/cache/providers/redis-cache.provider.d.ts +1 -0
  10. package/cache/providers/redis-cache.provider.js +8 -6
  11. package/http-client/config/http-client.config.js +4 -2
  12. package/http-client/decorators/http-client.decorators.d.ts +1 -1
  13. package/http-client/decorators/http-client.decorators.js +1 -1
  14. package/http-client/examples/advanced-usage.example.js +3 -3
  15. package/http-client/examples/axios-config-extended.example.js +1 -3
  16. package/http-client/examples/flexible-response-example.d.ts +28 -0
  17. package/http-client/examples/flexible-response-example.js +120 -0
  18. package/http-client/examples/ssl-certificate.example.d.ts +2 -2
  19. package/http-client/examples/ssl-certificate.example.js +18 -17
  20. package/http-client/http-client.module.js +2 -2
  21. package/http-client/interfaces/http-client-config.interface.d.ts +6 -1
  22. package/http-client/services/api-client-registry.service.d.ts +6 -6
  23. package/http-client/services/api-client-registry.service.js +9 -9
  24. package/http-client/services/circuit-breaker.service.d.ts +9 -9
  25. package/http-client/services/circuit-breaker.service.js +24 -24
  26. package/http-client/services/http-client.service.d.ts +30 -13
  27. package/http-client/services/http-client.service.js +76 -47
  28. package/http-client/services/logging.service.d.ts +17 -33
  29. package/http-client/services/logging.service.js +81 -169
  30. package/http-client/utils/curl-generator.util.js +2 -5
  31. package/http-client/utils/index.d.ts +1 -0
  32. package/http-client/utils/index.js +1 -0
  33. package/http-client/utils/proxy-environment.util.d.ts +12 -12
  34. package/http-client/utils/proxy-environment.util.js +25 -19
  35. package/http-client/utils/retry-recorder.util.d.ts +0 -4
  36. package/http-client/utils/retry-recorder.util.js +2 -27
  37. package/http-client/utils/sanitize.util.d.ts +58 -0
  38. package/http-client/utils/sanitize.util.js +188 -0
  39. package/http-client/utils/security-validator.util.d.ts +19 -19
  40. package/http-client/utils/security-validator.util.js +66 -64
  41. package/interceptors/http-logging-interceptor.service.d.ts +38 -0
  42. package/interceptors/http-logging-interceptor.service.js +167 -0
  43. package/interceptors/index.d.ts +1 -0
  44. package/interceptors/index.js +1 -0
  45. package/package.json +1 -1
  46. package/setup/bootstrap.setup.js +1 -1
  47. package/shared/services/api-config.service.js +3 -18
  48. package/vault/vault-config.service.js +1 -1
@@ -1,6 +1,7 @@
1
1
  import type { CacheOptions, CacheStats } from './interfaces';
2
2
  import { CacheLayer } from './interfaces';
3
3
  import { ClsCacheProvider, LRUCacheProvider, RedisCacheProvider } from './providers';
4
+ import { CacheSerializationService } from './cache-serialization.service';
4
5
  /**
5
6
  * Unified cache service with three-tier architecture
6
7
  *
@@ -16,10 +17,11 @@ export declare class CacheService {
16
17
  private readonly redisProvider;
17
18
  private readonly enableCompression;
18
19
  private readonly compressionThreshold;
20
+ private readonly serializationService;
19
21
  private readonly logger;
20
22
  private readonly providers;
21
23
  private readonly stats;
22
- constructor(clsProvider: ClsCacheProvider, lruProvider: LRUCacheProvider, redisProvider: RedisCacheProvider, enableCompression?: boolean, compressionThreshold?: number);
24
+ constructor(clsProvider: ClsCacheProvider, lruProvider: LRUCacheProvider, redisProvider: RedisCacheProvider, enableCompression?: boolean, compressionThreshold?: number, serializationService?: CacheSerializationService);
23
25
  /**
24
26
  * Get or set cache value with factory function
25
27
  *
@@ -40,12 +40,13 @@ const cache_constants_1 = require("./cache.constants");
40
40
  * Supports automatic fallback, backfill, and dependency-based invalidation.
41
41
  */
42
42
  let CacheService = CacheService_1 = class CacheService {
43
- constructor(clsProvider, lruProvider, redisProvider, enableCompression = false, compressionThreshold = 1024) {
43
+ constructor(clsProvider, lruProvider, redisProvider, enableCompression = false, compressionThreshold = 1024, serializationService = new cache_serialization_service_1.CacheSerializationService()) {
44
44
  this.clsProvider = clsProvider;
45
45
  this.lruProvider = lruProvider;
46
46
  this.redisProvider = redisProvider;
47
47
  this.enableCompression = enableCompression;
48
48
  this.compressionThreshold = compressionThreshold;
49
+ this.serializationService = serializationService;
49
50
  this.logger = new common_1.Logger(CacheService_1.name);
50
51
  this.providers = new Map();
51
52
  this.stats = {
@@ -125,8 +126,7 @@ let CacheService = CacheService_1 = class CacheService {
125
126
  if (value !== null) {
126
127
  // Check if value is compressed and decompress if needed
127
128
  if (this.enableCompression && Buffer.isBuffer(value)) {
128
- const serializationService = new cache_serialization_service_1.CacheSerializationService();
129
- const decompressed = yield serializationService.deserialize(value);
129
+ const decompressed = yield this.serializationService.deserialize(value);
130
130
  value = decompressed.data;
131
131
  }
132
132
  // Cache hit
@@ -206,14 +206,14 @@ let CacheService = CacheService_1 = class CacheService {
206
206
  return __awaiter(this, void 0, void 0, function* () {
207
207
  this.stats.totalDeletes++;
208
208
  const targetLayers = layers || this.getDefaultLayers();
209
- const keys = Array.isArray(key) ? key : [key];
210
209
  const promises = targetLayers.map((layer) => __awaiter(this, void 0, void 0, function* () {
211
210
  const provider = this.providers.get(layer);
212
211
  if (!provider) {
213
212
  return;
214
213
  }
215
214
  try {
216
- yield provider.delete(keys);
215
+ // Pass the key directly (string or array) to the provider
216
+ yield provider.delete(key);
217
217
  }
218
218
  catch (error) {
219
219
  this.logger.warn(`Failed to delete from ${layer} cache: ${error instanceof Error ? error.message : String(error)}`);
@@ -357,8 +357,7 @@ let CacheService = CacheService_1 = class CacheService {
357
357
  value !== null &&
358
358
  value !== undefined &&
359
359
  JSON.stringify(value).length >= this.compressionThreshold) {
360
- const serializationService = new cache_serialization_service_1.CacheSerializationService();
361
- const compressed = yield serializationService.serialize(value, {
360
+ const compressed = yield this.serializationService.serialize(value, {
362
361
  compress: true,
363
362
  compressThreshold: this.compressionThreshold,
364
363
  });
@@ -471,7 +470,8 @@ exports.CacheService = CacheService = CacheService_1 = __decorate([
471
470
  __param(3, (0, common_1.Inject)(cache_constants_1.CACHE_COMPRESSION_ENABLED)),
472
471
  __param(4, (0, common_1.Optional)()),
473
472
  __param(4, (0, common_1.Inject)(cache_constants_1.CACHE_COMPRESSION_THRESHOLD)),
473
+ __param(5, (0, common_1.Optional)()),
474
474
  __metadata("design:paramtypes", [providers_1.ClsCacheProvider,
475
475
  providers_1.LRUCacheProvider,
476
- providers_1.RedisCacheProvider, Boolean, Number])
476
+ providers_1.RedisCacheProvider, Boolean, Number, cache_serialization_service_1.CacheSerializationService])
477
477
  ], CacheService);
@@ -71,13 +71,14 @@ function CachePut(options = {}) {
71
71
  }
72
72
  // Generate cache key
73
73
  const key = utils_1.KeyGenerator.generate(options, args);
74
- // Update cache with result
75
- yield cacheService.set(key, result, options);
74
+ // Update cache with result - don't await, let it happen in background
75
+ cacheService.set(key, result, options).catch((error) => {
76
+ logger.warn(`Failed to update cache for ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
77
+ });
76
78
  return result;
77
79
  }
78
80
  catch (error) {
79
- logger.error(`Cache put error in ${target.constructor.name}.${methodName}: ${error instanceof Error ? error.message : String(error)}`);
80
- // Re-throw the error (cache update failure shouldn't hide method errors)
81
+ // Method execution error - rethrow it
81
82
  throw error;
82
83
  }
83
84
  });
@@ -65,6 +65,11 @@ class CallbackDependency {
65
65
  return __awaiter(this, void 0, void 0, function* () {
66
66
  try {
67
67
  const currentData = yield this.getData();
68
+ // If oldData is null or undefined, consider it as changed
69
+ // (no previous valid data exists)
70
+ if (oldData === null || oldData === undefined) {
71
+ return true;
72
+ }
68
73
  return !this.isEqual(oldData, currentData);
69
74
  }
70
75
  catch (_a) {
@@ -86,6 +91,10 @@ class CallbackDependency {
86
91
  if (typeof a !== typeof b) {
87
92
  return false;
88
93
  }
94
+ // Handle Date objects
95
+ if (a instanceof Date && b instanceof Date) {
96
+ return a.getTime() === b.getTime();
97
+ }
89
98
  if (typeof a !== 'object') {
90
99
  return a === b;
91
100
  }
@@ -28,6 +28,7 @@ export declare class TagDependency implements CacheDependency {
28
28
  private readonly tags;
29
29
  private static readonly PREFIX;
30
30
  private static readonly REDIS_KEY_PREFIX;
31
+ private static readonly logger;
31
32
  private static tagVersions;
32
33
  private static redis;
33
34
  constructor(tags: string[]);
@@ -71,15 +72,6 @@ export declare class TagDependency implements CacheDependency {
71
72
  * @returns Map of tag names to versions
72
73
  */
73
74
  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;
83
75
  getKey(): string;
84
76
  getData(): Promise<Record<string, number>>;
85
77
  isChanged(oldData: Record<string, number>): Promise<boolean>;
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.TagDependency = void 0;
13
+ const common_1 = require("@nestjs/common");
13
14
  /**
14
15
  * Tag-based cache dependency
15
16
  *
@@ -73,7 +74,7 @@ class TagDependency {
73
74
  }
74
75
  catch (error) {
75
76
  // 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
+ TagDependency.logger.warn(`Failed to get tag version from Redis: ${error instanceof Error ? error.message : String(error)}`);
77
78
  }
78
79
  }
79
80
  // Fall back to in-memory storage
@@ -99,7 +100,7 @@ class TagDependency {
99
100
  yield TagDependency.redis.set(key, newVersion.toString());
100
101
  }
101
102
  catch (error) {
102
- console.error(`[TagDependency] Failed to invalidate tag in Redis: ${error instanceof Error ? error.message : String(error)}`);
103
+ TagDependency.logger.error(`Failed to invalidate tag in Redis: ${error instanceof Error ? error.message : String(error)}`);
103
104
  }
104
105
  }
105
106
  });
@@ -140,7 +141,7 @@ class TagDependency {
140
141
  }
141
142
  }
142
143
  catch (error) {
143
- console.error(`[TagDependency] Failed to reset tags in Redis: ${error instanceof Error ? error.message : String(error)}`);
144
+ TagDependency.logger.error(`Failed to reset tags in Redis: ${error instanceof Error ? error.message : String(error)}`);
144
145
  }
145
146
  }
146
147
  });
@@ -154,17 +155,6 @@ class TagDependency {
154
155
  static getAllTags() {
155
156
  return new Map(TagDependency.tagVersions);
156
157
  }
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;
167
- }
168
158
  getKey() {
169
159
  return `tag:${this.tags.sort().join(',')}`;
170
160
  }
@@ -203,6 +193,7 @@ class TagDependency {
203
193
  exports.TagDependency = TagDependency;
204
194
  TagDependency.PREFIX = 'cache:tag:';
205
195
  TagDependency.REDIS_KEY_PREFIX = 'cache:tag:versions';
196
+ TagDependency.logger = new common_1.Logger(TagDependency.name);
206
197
  // In-memory fallback for when Redis is not available
207
198
  TagDependency.tagVersions = new Map();
208
199
  // Redis client for distributed tag version storage
@@ -29,6 +29,7 @@ import { BaseCacheProvider } from './base-cache.provider';
29
29
  * ```
30
30
  */
31
31
  export declare class LRUCacheProvider extends BaseCacheProvider implements OnModuleDestroy {
32
+ private readonly logger;
32
33
  private cache;
33
34
  private namespace;
34
35
  private defaultTtl?;
@@ -17,6 +17,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
17
  step((generator = generator.apply(thisArg, _arguments || [])).next());
18
18
  });
19
19
  };
20
+ var LRUCacheProvider_1;
20
21
  Object.defineProperty(exports, "__esModule", { value: true });
21
22
  exports.LRUCacheProvider = void 0;
22
23
  const common_1 = require("@nestjs/common");
@@ -51,9 +52,10 @@ const LRUCacheClass = require('lru-cache').LRUCache;
51
52
  * });
52
53
  * ```
53
54
  */
54
- let LRUCacheProvider = class LRUCacheProvider extends base_cache_provider_1.BaseCacheProvider {
55
+ let LRUCacheProvider = LRUCacheProvider_1 = class LRUCacheProvider extends base_cache_provider_1.BaseCacheProvider {
55
56
  constructor(options) {
56
57
  super();
58
+ this.logger = new common_1.Logger(LRUCacheProvider_1.name);
57
59
  const { maxSize = 500, ttl, namespace = 'cache:lru' } = options || {};
58
60
  this.namespace = namespace;
59
61
  this.defaultTtl = ttl;
@@ -75,7 +77,7 @@ let LRUCacheProvider = class LRUCacheProvider extends base_cache_provider_1.Base
75
77
  return value !== undefined ? value : null;
76
78
  }
77
79
  catch (error) {
78
- console.warn(`LRUCacheProvider: Failed to get key ${key}:`, error);
80
+ this.logger.warn(`Failed to get key ${key}: ${error instanceof Error ? error.message : String(error)}`);
79
81
  return null;
80
82
  }
81
83
  });
@@ -161,7 +163,7 @@ let LRUCacheProvider = class LRUCacheProvider extends base_cache_provider_1.Base
161
163
  });
162
164
  }
163
165
  catch (error) {
164
- console.warn(`LRUCacheProvider: Failed to mget:`, error);
166
+ this.logger.warn(`Failed to mget: ${error instanceof Error ? error.message : String(error)}`);
165
167
  return keys.map(() => null);
166
168
  }
167
169
  });
@@ -220,7 +222,7 @@ let LRUCacheProvider = class LRUCacheProvider extends base_cache_provider_1.Base
220
222
  }
221
223
  };
222
224
  exports.LRUCacheProvider = LRUCacheProvider;
223
- exports.LRUCacheProvider = LRUCacheProvider = __decorate([
225
+ exports.LRUCacheProvider = LRUCacheProvider = LRUCacheProvider_1 = __decorate([
224
226
  (0, common_1.Injectable)(),
225
227
  __metadata("design:paramtypes", [Object])
226
228
  ], LRUCacheProvider);
@@ -14,6 +14,7 @@ export declare const REDIS_CLIENT: unique symbol;
14
14
  */
15
15
  export declare class RedisCacheProvider extends BaseCacheProvider {
16
16
  private readonly redis?;
17
+ private readonly logger;
17
18
  private readonly keyPrefix;
18
19
  constructor(redis?: Redis);
19
20
  getName(): string;
@@ -20,6 +20,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
20
20
  step((generator = generator.apply(thisArg, _arguments || [])).next());
21
21
  });
22
22
  };
23
+ var RedisCacheProvider_1;
23
24
  Object.defineProperty(exports, "__esModule", { value: true });
24
25
  exports.RedisCacheProvider = exports.REDIS_CLIENT = void 0;
25
26
  const common_1 = require("@nestjs/common");
@@ -36,13 +37,14 @@ exports.REDIS_CLIENT = Symbol('REDIS_CLIENT');
36
37
  *
37
38
  * Slowest but most persistent and widely shared cache layer.
38
39
  */
39
- let RedisCacheProvider = class RedisCacheProvider extends base_cache_provider_1.BaseCacheProvider {
40
+ let RedisCacheProvider = RedisCacheProvider_1 = class RedisCacheProvider extends base_cache_provider_1.BaseCacheProvider {
40
41
  constructor(redis) {
41
42
  super();
42
43
  this.redis = redis;
44
+ this.logger = new common_1.Logger(RedisCacheProvider_1.name);
43
45
  this.keyPrefix = 'cache:';
44
46
  if (!redis) {
45
- console.warn('RedisCacheProvider: Redis client not injected. Redis caching will be disabled.');
47
+ this.logger.warn('Redis client not injected. Redis caching will be disabled.');
46
48
  }
47
49
  }
48
50
  getName() {
@@ -62,7 +64,7 @@ let RedisCacheProvider = class RedisCacheProvider extends base_cache_provider_1.
62
64
  return JSON.parse(value);
63
65
  }
64
66
  catch (error) {
65
- console.warn(`RedisCacheProvider: Failed to get key ${key}: ${error instanceof Error ? error.message : String(error)}`);
67
+ this.logger.warn(`Failed to get key ${key}: ${error instanceof Error ? error.message : String(error)}`);
66
68
  return null;
67
69
  }
68
70
  });
@@ -126,7 +128,7 @@ let RedisCacheProvider = class RedisCacheProvider extends base_cache_provider_1.
126
128
  return deletedCount;
127
129
  }
128
130
  catch (error) {
129
- console.warn(`RedisCacheProvider: deletePattern failed: ${error instanceof Error ? error.message : String(error)}`);
131
+ this.logger.warn(`deletePattern failed: ${error instanceof Error ? error.message : String(error)}`);
130
132
  return 0;
131
133
  }
132
134
  });
@@ -184,7 +186,7 @@ let RedisCacheProvider = class RedisCacheProvider extends base_cache_provider_1.
184
186
  });
185
187
  }
186
188
  catch (error) {
187
- console.warn(`RedisCacheProvider: mget failed: ${error instanceof Error ? error.message : String(error)}`);
189
+ this.logger.warn(`mget failed: ${error instanceof Error ? error.message : String(error)}`);
188
190
  return keys.map(() => null);
189
191
  }
190
192
  });
@@ -236,7 +238,7 @@ let RedisCacheProvider = class RedisCacheProvider extends base_cache_provider_1.
236
238
  }
237
239
  };
238
240
  exports.RedisCacheProvider = RedisCacheProvider;
239
- exports.RedisCacheProvider = RedisCacheProvider = __decorate([
241
+ exports.RedisCacheProvider = RedisCacheProvider = RedisCacheProvider_1 = __decorate([
240
242
  (0, common_1.Injectable)(),
241
243
  __param(0, (0, common_1.Optional)()),
242
244
  __param(0, (0, common_1.Inject)(exports.REDIS_CLIENT)),
@@ -10,7 +10,9 @@ exports.getHttpClientConfig = getHttpClientConfig;
10
10
  function deepMerge(target, source) {
11
11
  const result = Object.assign({}, target);
12
12
  for (const key in source) {
13
- if (source[key] instanceof Object && key in target && !Array.isArray(source[key])) {
13
+ if (source[key] instanceof Object &&
14
+ key in target &&
15
+ !Array.isArray(source[key])) {
14
16
  result[key] = deepMerge(target[key], source[key]);
15
17
  }
16
18
  else {
@@ -60,7 +62,7 @@ exports.DEFAULT_HTTP_CLIENT_CONFIG = {
60
62
  logHeaders: false, // 默认不记录头信息(安全考虑)
61
63
  logBody: true,
62
64
  maxBodyLength: 1000,
63
- sanitizeHeaders: ['authorization', 'apikey', 'password', 'token', 'cookie'],
65
+ sanitize: ['password', 'secret', 'token', 'apiKey', 'authorization', 'cookie'],
64
66
  logLevel: 'info',
65
67
  databaseLogging: {
66
68
  enabled: false, // 默认不启用数据库日志
@@ -40,7 +40,7 @@ export declare const HttpCircuitBreaker: (options?: {
40
40
  export declare const HttpLogRequest: (options?: {
41
41
  logHeaders?: boolean;
42
42
  logBody?: boolean;
43
- sanitizeHeaders?: string[];
43
+ sanitize?: string[];
44
44
  databaseLog?: boolean;
45
45
  logLevel?: "debug" | "info" | "warn" | "error";
46
46
  serviceClass?: string;
@@ -125,7 +125,7 @@ const HttpLogRequest = (options = {}) => {
125
125
  const loggingOptions = {
126
126
  logHeaders: (_a = options.logHeaders) !== null && _a !== void 0 ? _a : true,
127
127
  logBody: (_b = options.logBody) !== null && _b !== void 0 ? _b : true,
128
- sanitizeHeaders: options.sanitizeHeaders || [
128
+ sanitize: options.sanitize || [
129
129
  'authorization',
130
130
  'apikey',
131
131
  'password',
@@ -158,7 +158,7 @@ __decorate([
158
158
  logHeaders: true,
159
159
  logBody: true,
160
160
  databaseLog: true,
161
- sanitizeHeaders: ['authorization', 'x-api-key'],
161
+ sanitize: ['authorization', 'x-api-key'],
162
162
  }),
163
163
  __metadata("design:type", Function),
164
164
  __metadata("design:paramtypes", [Object, String]),
@@ -185,7 +185,7 @@ exports.GitHubHttpService = GitHubHttpService = __decorate([
185
185
  logHeaders: true,
186
186
  logBody: true,
187
187
  maxBodyLength: 1000,
188
- sanitizeHeaders: ['authorization'],
188
+ sanitize: ['authorization'],
189
189
  logLevel: 'info',
190
190
  },
191
191
  }),
@@ -315,7 +315,7 @@ exports.PaymentHttpService = PaymentHttpService = __decorate([
315
315
  logHeaders: false, // 不记录敏感头信息
316
316
  logBody: false, // 不记录支付数据
317
317
  maxBodyLength: 1000,
318
- sanitizeHeaders: ['authorization', 'x-api-key', 'x-client-secret'],
318
+ sanitize: ['authorization', 'x-api-key', 'x-client-secret'],
319
319
  logLevel: 'info',
320
320
  },
321
321
  }),
@@ -304,9 +304,7 @@ function environmentSpecificConfig() {
304
304
  ? (status) => status >= 200 && status < 500
305
305
  : (status) => status >= 200 && status < 300,
306
306
  // 开发环境禁用 keep-alive 以便调试
307
- httpAgent: isDevelopment
308
- ? undefined
309
- : new http_1.Agent({ keepAlive: true }),
307
+ httpAgent: isDevelopment ? undefined : new http_1.Agent({ keepAlive: true }),
310
308
  },
311
309
  };
312
310
  return config;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * HttpClientService 灵活返回示例
3
+ * 展示如何根据不同需求获取不同的响应数据
4
+ */
5
+ import { HttpClientService } from '../services/http-client.service';
6
+ declare function getFullResponseExample(httpClient: HttpClientService): Promise<any>;
7
+ declare function getCustomResponseExample(httpClient: HttpClientService): Promise<any>;
8
+ declare function getPagedResponseExample(httpClient: HttpClientService): Promise<{
9
+ data: any;
10
+ currentPage: number;
11
+ pageSize: number;
12
+ totalPages: number;
13
+ totalItems: number;
14
+ hasNextPage: any;
15
+ hasPrevPage: any;
16
+ }>;
17
+ declare function getRedirectUrlExample(httpClient: HttpClientService): Promise<{
18
+ redirected: boolean;
19
+ url: any;
20
+ data?: undefined;
21
+ } | {
22
+ redirected: boolean;
23
+ data: any;
24
+ url?: undefined;
25
+ }>;
26
+ declare function getDefaultBehaviorExample(httpClient: HttpClientService): Promise<any>;
27
+ declare function conditionalReturnExample(httpClient: HttpClientService, needHeaders: boolean): Promise<any>;
28
+ export { getFullResponseExample, getCustomResponseExample, getPagedResponseExample, getRedirectUrlExample, getDefaultBehaviorExample, conditionalReturnExample, };
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ /**
3
+ * HttpClientService 灵活返回示例
4
+ * 展示如何根据不同需求获取不同的响应数据
5
+ */
6
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
+ return new (P || (P = Promise))(function (resolve, reject) {
9
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
13
+ });
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.getFullResponseExample = getFullResponseExample;
17
+ exports.getCustomResponseExample = getCustomResponseExample;
18
+ exports.getPagedResponseExample = getPagedResponseExample;
19
+ exports.getRedirectUrlExample = getRedirectUrlExample;
20
+ exports.getDefaultBehaviorExample = getDefaultBehaviorExample;
21
+ exports.conditionalReturnExample = conditionalReturnExample;
22
+ // 示例1: 获取完整响应对象(包含headers, status等)
23
+ function getFullResponseExample(httpClient) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ // 返回完整的AxiosResponse对象
26
+ const fullResponse = yield httpClient.get('https://api.example.com/data', {}, // config
27
+ 'my-client', // clientName
28
+ { returnType: 'full' });
29
+ // 现在可以访问headers、status等信息
30
+ console.log('Status:', fullResponse.status);
31
+ console.log('Headers:', fullResponse.headers);
32
+ console.log('Data:', fullResponse.data);
33
+ // 例如检查特定header
34
+ const contentType = fullResponse.headers['content-type'];
35
+ const location = fullResponse.headers['location'];
36
+ return fullResponse.data; // 仍然可以获取data
37
+ });
38
+ }
39
+ // 示例2: 自定义返回格式
40
+ function getCustomResponseExample(httpClient) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ // 自定义转换函数 - 只返回需要的字段
43
+ const customResponse = yield httpClient.get('https://api.example.com/users', {}, 'my-client', {
44
+ returnType: 'custom',
45
+ transform: (response) => {
46
+ var _a;
47
+ return ({
48
+ data: response.data,
49
+ totalCount: response.headers['x-total-count'],
50
+ currentPage: response.headers['x-current-page'],
51
+ hasNext: (_a = response.headers['link']) === null || _a === void 0 ? void 0 : _a.includes('rel="next"'),
52
+ });
53
+ },
54
+ });
55
+ console.log('Total Count:', customResponse.totalCount);
56
+ console.log('Has Next Page:', customResponse.hasNext);
57
+ return customResponse;
58
+ });
59
+ }
60
+ // 示例3: 从headers中提取分页信息
61
+ function getPagedResponseExample(httpClient) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ var _a, _b;
64
+ const response = yield httpClient.get('https://api.example.com/items?page=1&size=10', {}, 'my-client', { returnType: 'full' });
65
+ // 提取分页信息
66
+ const paginationInfo = {
67
+ data: response.data,
68
+ currentPage: parseInt(response.headers['x-page'] || '1'),
69
+ pageSize: parseInt(response.headers['x-per-page'] || '10'),
70
+ totalPages: parseInt(response.headers['x-total-pages'] || '1'),
71
+ totalItems: parseInt(response.headers['x-total-items'] || '0'),
72
+ hasNextPage: ((_a = response.headers['link']) === null || _a === void 0 ? void 0 : _a.includes('rel="next"')) || false,
73
+ hasPrevPage: ((_b = response.headers['link']) === null || _b === void 0 ? void 0 : _b.includes('rel="prev"')) || false,
74
+ };
75
+ return paginationInfo;
76
+ });
77
+ }
78
+ // 示例4: 检查重定向URL
79
+ function getRedirectUrlExample(httpClient) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ const response = yield httpClient.get('https://api.example.com/redirect-me', { maxRedirects: 0 }, // 禁止自动重定向以便捕获Location header
82
+ 'my-client', { returnType: 'full' });
83
+ // 对于3xx重定向状态,获取重定向URL
84
+ if (response.status >= 300 && response.status < 400) {
85
+ const redirectUrl = response.headers['location'];
86
+ console.log('Redirect URL:', redirectUrl);
87
+ return { redirected: true, url: redirectUrl };
88
+ }
89
+ return { redirected: false, data: response.data };
90
+ });
91
+ }
92
+ // 示例5: 向后兼容 - 默认行为(只返回data)
93
+ function getDefaultBehaviorExample(httpClient) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ // 不传递returnOptions参数,保持原有行为
96
+ const data = yield httpClient.get('https://api.example.com/simple-data');
97
+ // 直接得到data,无需.response.data
98
+ console.log('Simple data:', data);
99
+ return data;
100
+ });
101
+ }
102
+ // 示例6: 条件性返回不同格式
103
+ function conditionalReturnExample(httpClient, needHeaders) {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ const returnOptions = needHeaders
106
+ ? { returnType: 'full' }
107
+ : { returnType: 'data' }; // 默认
108
+ const result = yield httpClient.post('https://api.example.com/process', { action: 'calculate' }, {}, 'my-client', returnOptions);
109
+ if (needHeaders) {
110
+ // 处理完整响应
111
+ const fullResponse = result;
112
+ console.log('Processing time:', fullResponse.headers['x-processing-time']);
113
+ return fullResponse.data;
114
+ }
115
+ else {
116
+ // 直接使用data
117
+ return result;
118
+ }
119
+ });
120
+ }
@@ -27,10 +27,10 @@ export declare class DynamicCertificateManager {
27
27
  cert?: string;
28
28
  key?: string;
29
29
  });
30
- private loadCerts;
31
- private buildConfig;
32
30
  refreshCerts(): Promise<void>;
33
31
  get(url: string): Promise<void>;
32
+ private loadCerts;
33
+ private buildConfig;
34
34
  }
35
35
  export declare const sslEnvVars: {
36
36
  SSL_CA_PATH: string;
@@ -339,9 +339,26 @@ class DynamicCertificateManager {
339
339
  this.cacheDuration = 5 * 60 * 1000; // 5分钟
340
340
  this.httpClient = new index_1.HttpClientService(this.circuitBreakerService, this.loggingService, null, this.buildConfig());
341
341
  }
342
+ // 重新创建客户端以使用新证书
343
+ refreshCerts() {
344
+ return __awaiter(this, void 0, void 0, function* () {
345
+ this.lastUpdate = 0;
346
+ const config = this.buildConfig();
347
+ // 在实际应用中,可能需要重新创建 HttpClientService 实例
348
+ // 或者提供更新配置的方法
349
+ });
350
+ }
351
+ get(url) {
352
+ return __awaiter(this, void 0, void 0, function* () {
353
+ // 每次请求前检查是否需要更新证书
354
+ this.loadCerts();
355
+ // return this.httpClient.get(url);
356
+ });
357
+ }
342
358
  loadCerts() {
343
359
  const now = Date.now();
344
- if (now - this.lastUpdate < this.cacheDuration && Object.keys(this.certCache).length > 0) {
360
+ if (now - this.lastUpdate < this.cacheDuration &&
361
+ Object.keys(this.certCache).length > 0) {
345
362
  return this.certCache;
346
363
  }
347
364
  // 重新加载证书
@@ -367,22 +384,6 @@ class DynamicCertificateManager {
367
384
  },
368
385
  };
369
386
  }
370
- // 重新创建客户端以使用新证书
371
- refreshCerts() {
372
- return __awaiter(this, void 0, void 0, function* () {
373
- this.lastUpdate = 0;
374
- const config = this.buildConfig();
375
- // 在实际应用中,可能需要重新创建 HttpClientService 实例
376
- // 或者提供更新配置的方法
377
- });
378
- }
379
- get(url) {
380
- return __awaiter(this, void 0, void 0, function* () {
381
- // 每次请求前检查是否需要更新证书
382
- this.loadCerts();
383
- // return this.httpClient.get(url);
384
- });
385
- }
386
387
  }
387
388
  exports.DynamicCertificateManager = DynamicCertificateManager;
388
389
  // ============================================================================
@@ -295,8 +295,8 @@ let HttpClientModule = HttpClientModule_1 = class HttpClientModule {
295
295
  maxBodyLength: configService.get('HTTP_CLIENT_LOG_MAX_BODY_LENGTH')
296
296
  ? parseInt(configService.get('HTTP_CLIENT_LOG_MAX_BODY_LENGTH'))
297
297
  : undefined,
298
- sanitizeHeaders: (_a = configService
299
- .get('HTTP_CLIENT_LOG_SANITIZE_HEADERS')) === null || _a === void 0 ? void 0 : _a.split(','),
298
+ sanitize: (_a = configService
299
+ .get('HTTP_CLIENT_LOG_SANITIZE')) === null || _a === void 0 ? void 0 : _a.split(','),
300
300
  logLevel: configService.get('HTTP_CLIENT_LOG_LEVEL'),
301
301
  databaseLogging: {
302
302
  enabled: configService.get('HTTP_CLIENT_DB_LOGGING_ENABLED') ===