@nest-omni/core 4.1.3-1 → 4.1.3-3
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.
- package/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +15 -0
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +8 -0
- package/audit/decorators/audit-controller.decorator.js +9 -0
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +8 -0
- package/audit/decorators/entity-audit.decorator.js +9 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +3 -0
- package/audit/entities/entity-audit-log.entity.js +3 -0
- package/audit/entities/entity-transaction.entity.d.ts +3 -0
- package/audit/entities/entity-transaction.entity.js +3 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +17 -2
- package/audit/enums/audit.enums.js +15 -0
- package/audit/index.js +10 -0
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +42 -0
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +57 -0
- package/audit/services/entity-audit.service.js +91 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -4
- package/common/boilerplate.polyfill.js +24 -100
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +19 -0
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.js +3 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +60 -0
- package/redis-lock/redis-lock.module.js +46 -0
- package/redis-lock/redis-lock.service.d.ts +251 -0
- package/redis-lock/redis-lock.service.js +219 -3
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +226 -0
- package/setup/schedule.decorator.js +214 -1
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +9 -1
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +133 -0
- package/validators/custom-validate.validator.js +213 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +19 -4
- package/validators/is-unique.validator.js +67 -11
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -23,11 +23,18 @@ exports.HttpCacheService = void 0;
|
|
|
23
23
|
const common_1 = require("@nestjs/common");
|
|
24
24
|
const cache_service_1 = require("../../cache/cache.service");
|
|
25
25
|
const cache_options_interface_1 = require("../../cache/interfaces/cache-options.interface");
|
|
26
|
+
/**
|
|
27
|
+
* HTTP缓存服务
|
|
28
|
+
* 集成现有的三层缓存架构
|
|
29
|
+
*/
|
|
26
30
|
let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
27
31
|
constructor(cacheService) {
|
|
28
32
|
this.cacheService = cacheService;
|
|
29
33
|
this.logger = new common_1.Logger(HttpCacheService_1.name);
|
|
30
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* 获取缓存的响应
|
|
37
|
+
*/
|
|
31
38
|
get(config, cacheOptions) {
|
|
32
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
33
40
|
var _a;
|
|
@@ -51,6 +58,9 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
51
58
|
}
|
|
52
59
|
});
|
|
53
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 缓存响应
|
|
63
|
+
*/
|
|
54
64
|
set(config, response, cacheOptions) {
|
|
55
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
66
|
var _a, _b, _c, _d;
|
|
@@ -75,14 +85,19 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
75
85
|
}
|
|
76
86
|
});
|
|
77
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* 清除缓存
|
|
90
|
+
*/
|
|
78
91
|
clear(pattern) {
|
|
79
92
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
93
|
try {
|
|
81
94
|
if (pattern) {
|
|
95
|
+
// 使用通配符清除
|
|
82
96
|
yield this.cacheService.deletePattern(pattern);
|
|
83
97
|
this.logger.debug(`Cache cleared with pattern: ${pattern}`);
|
|
84
98
|
}
|
|
85
99
|
else {
|
|
100
|
+
// 清除所有HTTP相关缓存
|
|
86
101
|
yield this.cacheService.deletePattern('http:*');
|
|
87
102
|
this.logger.debug('All HTTP cache cleared');
|
|
88
103
|
}
|
|
@@ -92,6 +107,9 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
92
107
|
}
|
|
93
108
|
});
|
|
94
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* 获取缓存统计信息
|
|
112
|
+
*/
|
|
95
113
|
getStats() {
|
|
96
114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
115
|
try {
|
|
@@ -104,9 +122,13 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
104
122
|
}
|
|
105
123
|
});
|
|
106
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* 清理过期缓存
|
|
127
|
+
*/
|
|
107
128
|
cleanup() {
|
|
108
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
130
|
try {
|
|
131
|
+
// CacheService doesn't have cleanup method, so we'll clear HTTP cache patterns
|
|
110
132
|
yield this.cacheService.deletePattern('http:*');
|
|
111
133
|
this.logger.debug('HTTP cache cleanup completed');
|
|
112
134
|
}
|
|
@@ -115,12 +137,21 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
115
137
|
}
|
|
116
138
|
});
|
|
117
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* 预热缓存
|
|
142
|
+
*/
|
|
118
143
|
warmup(urls, headers) {
|
|
119
144
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
145
|
this.logger.log(`Starting cache warmup for ${urls.length} URLs`);
|
|
146
|
+
// 这里可以实现预热逻辑
|
|
147
|
+
// 例如:预先请求这些URL并缓存响应
|
|
148
|
+
// 实际实现需要访问HTTP客户端服务,可能需要通过事件或其他方式实现
|
|
121
149
|
this.logger.log('Cache warmup completed');
|
|
122
150
|
});
|
|
123
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* 获取缓存命中率详情
|
|
154
|
+
*/
|
|
124
155
|
getDetailedStats() {
|
|
125
156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
157
|
try {
|
|
@@ -134,11 +165,15 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
134
165
|
}
|
|
135
166
|
});
|
|
136
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* 生成缓存键
|
|
170
|
+
*/
|
|
137
171
|
generateCacheKey(config, cacheOptions) {
|
|
138
172
|
var _a;
|
|
139
173
|
if (cacheOptions.keyGenerator) {
|
|
140
174
|
return cacheOptions.keyGenerator(config);
|
|
141
175
|
}
|
|
176
|
+
// 默认键生成逻辑
|
|
142
177
|
const keyData = {
|
|
143
178
|
method: (_a = config.method) === null || _a === void 0 ? void 0 : _a.toLowerCase(),
|
|
144
179
|
url: config.url,
|
|
@@ -146,16 +181,23 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
146
181
|
data: config.data,
|
|
147
182
|
headers: this.selectHeadersForCacheKey(config.headers),
|
|
148
183
|
};
|
|
184
|
+
// 简单的哈希键生成
|
|
149
185
|
return this.hashObject(keyData);
|
|
150
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* 构建完整的缓存键
|
|
189
|
+
*/
|
|
151
190
|
buildCacheKey(cacheOptions, key) {
|
|
152
191
|
var _a;
|
|
153
192
|
const namespace = ((_a = cacheOptions.options) === null || _a === void 0 ? void 0 : _a.prefix) || 'http';
|
|
154
193
|
return `${namespace}:${key}`;
|
|
155
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* 映射缓存层
|
|
197
|
+
*/
|
|
156
198
|
mapLayers(layers) {
|
|
157
199
|
if (!layers || layers.length === 0) {
|
|
158
|
-
return [cache_options_interface_1.CacheLayer.MEMORY, cache_options_interface_1.CacheLayer.REDIS];
|
|
200
|
+
return [cache_options_interface_1.CacheLayer.MEMORY, cache_options_interface_1.CacheLayer.REDIS]; // 默认使用内存和Redis
|
|
159
201
|
}
|
|
160
202
|
return layers.map((layer) => {
|
|
161
203
|
switch (layer) {
|
|
@@ -170,15 +212,19 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
170
212
|
}
|
|
171
213
|
});
|
|
172
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* 选择用于缓存键的头信息
|
|
217
|
+
*/
|
|
173
218
|
selectHeadersForCacheKey(headers) {
|
|
174
219
|
if (!headers)
|
|
175
220
|
return {};
|
|
221
|
+
// 只选择影响响应内容的头信息
|
|
176
222
|
const cacheKeyHeaders = [
|
|
177
223
|
'accept',
|
|
178
224
|
'accept-language',
|
|
179
225
|
'accept-encoding',
|
|
180
226
|
'content-type',
|
|
181
|
-
'authorization',
|
|
227
|
+
'authorization', // 包含授权信息以确保缓存的安全性
|
|
182
228
|
];
|
|
183
229
|
const selectedHeaders = {};
|
|
184
230
|
cacheKeyHeaders.forEach((key) => {
|
|
@@ -188,15 +234,21 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
188
234
|
});
|
|
189
235
|
return selectedHeaders;
|
|
190
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* 判断响应是否可缓存
|
|
239
|
+
*/
|
|
191
240
|
isResponseCacheable(response, config) {
|
|
192
241
|
var _a;
|
|
242
|
+
// 检查状态码
|
|
193
243
|
if (!config.cacheableStatusCodes.includes(response.status)) {
|
|
194
244
|
return false;
|
|
195
245
|
}
|
|
246
|
+
// 检查方法
|
|
196
247
|
const method = (_a = response.config.method) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
197
248
|
if (!config.cacheableMethods.includes(method || 'get')) {
|
|
198
249
|
return false;
|
|
199
250
|
}
|
|
251
|
+
// 检查缓存控制头
|
|
200
252
|
const cacheControl = response.headers['cache-control'];
|
|
201
253
|
if (cacheControl) {
|
|
202
254
|
if (cacheControl.includes('no-store') ||
|
|
@@ -204,28 +256,37 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
204
256
|
return false;
|
|
205
257
|
}
|
|
206
258
|
if (cacheControl.includes('private')) {
|
|
259
|
+
// 私有缓存可能需要特殊处理
|
|
207
260
|
this.logger.debug('Private cache detected, caching with caution');
|
|
208
261
|
}
|
|
209
262
|
}
|
|
263
|
+
// 检查响应大小
|
|
210
264
|
if (response.data) {
|
|
211
265
|
const responseSize = JSON.stringify(response.data).length;
|
|
212
266
|
if (responseSize > 1024 * 1024) {
|
|
267
|
+
// 1MB限制
|
|
213
268
|
this.logger.warn(`Response too large for caching: ${responseSize} bytes`);
|
|
214
269
|
return false;
|
|
215
270
|
}
|
|
216
271
|
}
|
|
217
272
|
return true;
|
|
218
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* 哈希对象
|
|
276
|
+
*/
|
|
219
277
|
hashObject(obj) {
|
|
220
278
|
const str = JSON.stringify(obj, Object.keys(obj).sort());
|
|
221
279
|
let hash = 0;
|
|
222
280
|
for (let i = 0; i < str.length; i++) {
|
|
223
281
|
const char = str.charCodeAt(i);
|
|
224
282
|
hash = (hash << 5) - hash + char;
|
|
225
|
-
hash = hash & hash;
|
|
283
|
+
hash = hash & hash; // 转换为32位整数
|
|
226
284
|
}
|
|
227
285
|
return Math.abs(hash).toString(36);
|
|
228
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* 计算综合命中率
|
|
289
|
+
*/
|
|
229
290
|
calculateHitRate(...stats) {
|
|
230
291
|
let totalHits = 0;
|
|
231
292
|
let totalRequests = 0;
|
|
@@ -237,8 +298,13 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
237
298
|
});
|
|
238
299
|
return totalRequests > 0 ? (totalHits / totalRequests) * 100 : 0;
|
|
239
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* 获取最近的缓存活动
|
|
303
|
+
*/
|
|
240
304
|
getRecentCacheActivity() {
|
|
241
305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
306
|
+
// 这里可以实现获取最近缓存活动的逻辑
|
|
307
|
+
// 例如:从Redis获取最近的缓存键访问记录
|
|
242
308
|
return {
|
|
243
309
|
recentHits: 0,
|
|
244
310
|
recentMisses: 0,
|
|
@@ -246,6 +312,9 @@ let HttpCacheService = HttpCacheService_1 = class HttpCacheService {
|
|
|
246
312
|
};
|
|
247
313
|
});
|
|
248
314
|
}
|
|
315
|
+
/**
|
|
316
|
+
* 生成缓存优化建议
|
|
317
|
+
*/
|
|
249
318
|
generateRecommendations(stats) {
|
|
250
319
|
const recommendations = [];
|
|
251
320
|
if (stats.combined.hitRate < 50) {
|
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
import { Logger } from '@nestjs/common';
|
|
2
2
|
import { CircuitBreakerConfig } from '../interfaces/http-client-config.interface';
|
|
3
|
+
/**
|
|
4
|
+
* 熔断器服务
|
|
5
|
+
* 基于Spring Cloud CircuitBreaker的设计理念
|
|
6
|
+
*/
|
|
3
7
|
export declare class HttpCircuitBreakerService {
|
|
4
8
|
private readonly logger;
|
|
5
9
|
private readonly circuitBreakers;
|
|
10
|
+
/**
|
|
11
|
+
* 获取或创建熔断器
|
|
12
|
+
*/
|
|
6
13
|
getCircuitBreaker(key: string, config: CircuitBreakerConfig): CircuitBreaker;
|
|
14
|
+
/**
|
|
15
|
+
* 执行带熔断保护的请求
|
|
16
|
+
*/
|
|
7
17
|
executeWithCircuitBreaker<T>(key: string, requestFn: () => Promise<T>, config: CircuitBreakerConfig): Promise<T>;
|
|
18
|
+
/**
|
|
19
|
+
* 重置所有熔断器
|
|
20
|
+
*/
|
|
8
21
|
resetAll(): void;
|
|
22
|
+
/**
|
|
23
|
+
* 获取所有熔断器状态
|
|
24
|
+
*/
|
|
9
25
|
getAllStates(): Record<string, any>;
|
|
10
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* 熔断器类
|
|
29
|
+
*/
|
|
11
30
|
declare class CircuitBreaker {
|
|
12
31
|
private readonly key;
|
|
13
32
|
private readonly config;
|
|
@@ -20,14 +39,41 @@ declare class CircuitBreaker {
|
|
|
20
39
|
private requestCount;
|
|
21
40
|
private windowStartTime;
|
|
22
41
|
constructor(key: string, config: CircuitBreakerConfig, logger: Logger);
|
|
42
|
+
/**
|
|
43
|
+
* 执行请求
|
|
44
|
+
*/
|
|
23
45
|
execute<T>(requestFn: () => Promise<T>): Promise<T>;
|
|
46
|
+
/**
|
|
47
|
+
* 重置熔断器
|
|
48
|
+
*/
|
|
24
49
|
reset(): void;
|
|
50
|
+
/**
|
|
51
|
+
* 获取熔断器状态
|
|
52
|
+
*/
|
|
25
53
|
getState(): any;
|
|
54
|
+
/**
|
|
55
|
+
* 处理成功请求
|
|
56
|
+
*/
|
|
26
57
|
private onSuccess;
|
|
58
|
+
/**
|
|
59
|
+
* 处理失败请求
|
|
60
|
+
*/
|
|
27
61
|
private onFailure;
|
|
62
|
+
/**
|
|
63
|
+
* 转换到关闭状态
|
|
64
|
+
*/
|
|
28
65
|
private transitionToClosed;
|
|
66
|
+
/**
|
|
67
|
+
* 转换到开启状态
|
|
68
|
+
*/
|
|
29
69
|
private transitionToOpen;
|
|
70
|
+
/**
|
|
71
|
+
* 转换到半开状态
|
|
72
|
+
*/
|
|
30
73
|
private transitionToHalfOpen;
|
|
74
|
+
/**
|
|
75
|
+
* 重置监控窗口
|
|
76
|
+
*/
|
|
31
77
|
private resetMonitoringWindow;
|
|
32
78
|
}
|
|
33
79
|
export {};
|
|
@@ -18,32 +18,51 @@ var HttpCircuitBreakerService_1;
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.HttpCircuitBreakerService = void 0;
|
|
20
20
|
const common_1 = require("@nestjs/common");
|
|
21
|
+
/**
|
|
22
|
+
* 熔断器状态
|
|
23
|
+
*/
|
|
21
24
|
var CircuitBreakerState;
|
|
22
25
|
(function (CircuitBreakerState) {
|
|
23
26
|
CircuitBreakerState["CLOSED"] = "CLOSED";
|
|
24
27
|
CircuitBreakerState["OPEN"] = "OPEN";
|
|
25
28
|
CircuitBreakerState["HALF_OPEN"] = "HALF_OPEN";
|
|
26
29
|
})(CircuitBreakerState || (CircuitBreakerState = {}));
|
|
30
|
+
/**
|
|
31
|
+
* 熔断器服务
|
|
32
|
+
* 基于Spring Cloud CircuitBreaker的设计理念
|
|
33
|
+
*/
|
|
27
34
|
let HttpCircuitBreakerService = HttpCircuitBreakerService_1 = class HttpCircuitBreakerService {
|
|
28
35
|
constructor() {
|
|
29
36
|
this.logger = new common_1.Logger(HttpCircuitBreakerService_1.name);
|
|
30
37
|
this.circuitBreakers = new Map();
|
|
31
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* 获取或创建熔断器
|
|
41
|
+
*/
|
|
32
42
|
getCircuitBreaker(key, config) {
|
|
33
43
|
if (!this.circuitBreakers.has(key)) {
|
|
34
44
|
this.circuitBreakers.set(key, new CircuitBreaker(key, config, this.logger));
|
|
35
45
|
}
|
|
36
46
|
return this.circuitBreakers.get(key);
|
|
37
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* 执行带熔断保护的请求
|
|
50
|
+
*/
|
|
38
51
|
executeWithCircuitBreaker(key, requestFn, config) {
|
|
39
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40
53
|
const circuitBreaker = this.getCircuitBreaker(key, config);
|
|
41
54
|
return circuitBreaker.execute(requestFn);
|
|
42
55
|
});
|
|
43
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* 重置所有熔断器
|
|
59
|
+
*/
|
|
44
60
|
resetAll() {
|
|
45
61
|
this.circuitBreakers.forEach((cb) => cb.reset());
|
|
46
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* 获取所有熔断器状态
|
|
65
|
+
*/
|
|
47
66
|
getAllStates() {
|
|
48
67
|
const states = {};
|
|
49
68
|
this.circuitBreakers.forEach((cb, key) => {
|
|
@@ -56,6 +75,9 @@ exports.HttpCircuitBreakerService = HttpCircuitBreakerService;
|
|
|
56
75
|
exports.HttpCircuitBreakerService = HttpCircuitBreakerService = HttpCircuitBreakerService_1 = __decorate([
|
|
57
76
|
(0, common_1.Injectable)()
|
|
58
77
|
], HttpCircuitBreakerService);
|
|
78
|
+
/**
|
|
79
|
+
* 熔断器类
|
|
80
|
+
*/
|
|
59
81
|
class CircuitBreaker {
|
|
60
82
|
constructor(key, config, logger) {
|
|
61
83
|
this.key = key;
|
|
@@ -69,9 +91,13 @@ class CircuitBreaker {
|
|
|
69
91
|
this.requestCount = 0;
|
|
70
92
|
this.windowStartTime = Date.now();
|
|
71
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* 执行请求
|
|
96
|
+
*/
|
|
72
97
|
execute(requestFn) {
|
|
73
98
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74
99
|
const currentTime = Date.now();
|
|
100
|
+
// 检查是否需要重置监控窗口
|
|
75
101
|
if (currentTime - this.windowStartTime > this.config.monitoringPeriodMs) {
|
|
76
102
|
this.resetMonitoringWindow();
|
|
77
103
|
}
|
|
@@ -87,6 +113,7 @@ class CircuitBreaker {
|
|
|
87
113
|
break;
|
|
88
114
|
case CircuitBreakerState.CLOSED:
|
|
89
115
|
default:
|
|
116
|
+
// 正常状态,继续执行
|
|
90
117
|
break;
|
|
91
118
|
}
|
|
92
119
|
this.requestCount++;
|
|
@@ -101,10 +128,16 @@ class CircuitBreaker {
|
|
|
101
128
|
}
|
|
102
129
|
});
|
|
103
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* 重置熔断器
|
|
133
|
+
*/
|
|
104
134
|
reset() {
|
|
105
135
|
this.transitionToClosed();
|
|
106
136
|
this.resetMonitoringWindow();
|
|
107
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* 获取熔断器状态
|
|
140
|
+
*/
|
|
108
141
|
getState() {
|
|
109
142
|
return {
|
|
110
143
|
state: this.state,
|
|
@@ -117,6 +150,9 @@ class CircuitBreaker {
|
|
|
117
150
|
config: this.config,
|
|
118
151
|
};
|
|
119
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* 处理成功请求
|
|
155
|
+
*/
|
|
120
156
|
onSuccess() {
|
|
121
157
|
this.failureCount = 0;
|
|
122
158
|
switch (this.state) {
|
|
@@ -128,9 +164,13 @@ class CircuitBreaker {
|
|
|
128
164
|
break;
|
|
129
165
|
case CircuitBreakerState.CLOSED:
|
|
130
166
|
default:
|
|
167
|
+
// 保持关闭状态
|
|
131
168
|
break;
|
|
132
169
|
}
|
|
133
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* 处理失败请求
|
|
173
|
+
*/
|
|
134
174
|
onFailure() {
|
|
135
175
|
this.failureCount++;
|
|
136
176
|
this.lastFailureTime = Date.now();
|
|
@@ -148,6 +188,9 @@ class CircuitBreaker {
|
|
|
148
188
|
break;
|
|
149
189
|
}
|
|
150
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* 转换到关闭状态
|
|
193
|
+
*/
|
|
151
194
|
transitionToClosed() {
|
|
152
195
|
if (this.state !== CircuitBreakerState.CLOSED) {
|
|
153
196
|
this.logger.log(`Circuit breaker ${this.key} transitioned to CLOSED`);
|
|
@@ -156,6 +199,9 @@ class CircuitBreaker {
|
|
|
156
199
|
this.successCount = 0;
|
|
157
200
|
}
|
|
158
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* 转换到开启状态
|
|
204
|
+
*/
|
|
159
205
|
transitionToOpen() {
|
|
160
206
|
if (this.state !== CircuitBreakerState.OPEN) {
|
|
161
207
|
this.logger.warn(`Circuit breaker ${this.key} transitioned to OPEN due to ${this.failureCount} failures`);
|
|
@@ -164,6 +210,9 @@ class CircuitBreaker {
|
|
|
164
210
|
this.successCount = 0;
|
|
165
211
|
}
|
|
166
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* 转换到半开状态
|
|
215
|
+
*/
|
|
167
216
|
transitionToHalfOpen() {
|
|
168
217
|
if (this.state !== CircuitBreakerState.HALF_OPEN) {
|
|
169
218
|
this.logger.log(`Circuit breaker ${this.key} transitioned to HALF_OPEN`);
|
|
@@ -171,6 +220,9 @@ class CircuitBreaker {
|
|
|
171
220
|
this.successCount = 0;
|
|
172
221
|
}
|
|
173
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* 重置监控窗口
|
|
225
|
+
*/
|
|
174
226
|
resetMonitoringWindow() {
|
|
175
227
|
this.windowStartTime = Date.now();
|
|
176
228
|
this.requestCount = 0;
|
|
@@ -11,6 +11,10 @@ interface ExtendedAxiosRequestConfig extends AxiosRequestConfig {
|
|
|
11
11
|
[key: string]: any;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* HTTP客户端服务
|
|
16
|
+
* 基于Spring RestTemplate的设计理念,集成axios-retry库
|
|
17
|
+
*/
|
|
14
18
|
export declare class HttpClientService {
|
|
15
19
|
private readonly circuitBreakerService;
|
|
16
20
|
private readonly loggingService;
|
|
@@ -21,22 +25,55 @@ export declare class HttpClientService {
|
|
|
21
25
|
private readonly defaultConfig;
|
|
22
26
|
private requestStats;
|
|
23
27
|
constructor(circuitBreakerService: HttpCircuitBreakerService, loggingService: HttpLoggingService, cacheService: HttpCacheService, redisLockService?: RedisLockService, config?: HttpClientConfig);
|
|
28
|
+
/**
|
|
29
|
+
* 执行HTTP请求
|
|
30
|
+
*/
|
|
24
31
|
request<T = any>(config: ExtendedAxiosRequestConfig, decoratorContext?: any): Promise<T>;
|
|
32
|
+
/**
|
|
33
|
+
* 生成curl命令(动态生成,不存储)
|
|
34
|
+
*/
|
|
25
35
|
generateCurlCommand(config: ExtendedAxiosRequestConfig): string;
|
|
36
|
+
/**
|
|
37
|
+
* 生成调试curl命令(动态生成,不存储)
|
|
38
|
+
*/
|
|
26
39
|
generateDebugCurlCommand(config: ExtendedAxiosRequestConfig, response?: AxiosResponse): string;
|
|
40
|
+
/**
|
|
41
|
+
* 获取请求统计信息
|
|
42
|
+
*/
|
|
27
43
|
getStats(): any;
|
|
44
|
+
/**
|
|
45
|
+
* 重置统计信息
|
|
46
|
+
*/
|
|
28
47
|
resetStats(): void;
|
|
29
48
|
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
30
49
|
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
31
50
|
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
32
51
|
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
|
|
33
52
|
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
53
|
+
/**
|
|
54
|
+
* 带等待锁的认证请求方法
|
|
55
|
+
* 用于需要确保只有一个进程执行认证相关操作的场景
|
|
56
|
+
*
|
|
57
|
+
* @param config 请求配置
|
|
58
|
+
* @param tokenProvider token提供函数
|
|
59
|
+
* @param options 等待锁选项
|
|
60
|
+
* @returns 响应数据
|
|
61
|
+
*/
|
|
34
62
|
authRequest<T = any>(config: AxiosRequestConfig, tokenProvider: () => Promise<string>, options?: {
|
|
35
63
|
lockKey?: string;
|
|
36
64
|
lockTimeout?: number;
|
|
37
65
|
waitTimeout?: number;
|
|
38
66
|
enableRetry?: boolean;
|
|
39
67
|
}): Promise<T>;
|
|
68
|
+
/**
|
|
69
|
+
* 带等待锁的批量认证请求
|
|
70
|
+
* 用于需要批量执行认证相关操作但避免重复认证的场景
|
|
71
|
+
*
|
|
72
|
+
* @param requests 请求数组
|
|
73
|
+
* @param tokenProvider token提供函数
|
|
74
|
+
* @param options 等待锁选项
|
|
75
|
+
* @returns 响应数组
|
|
76
|
+
*/
|
|
40
77
|
authBatchRequest<T = any>(requests: Array<{
|
|
41
78
|
config: AxiosRequestConfig;
|
|
42
79
|
key: string;
|
|
@@ -46,15 +83,45 @@ export declare class HttpClientService {
|
|
|
46
83
|
waitTimeout?: number;
|
|
47
84
|
maxConcurrency?: number;
|
|
48
85
|
}): Promise<Array<T | null>>;
|
|
86
|
+
/**
|
|
87
|
+
* 创建Axios实例并配置axios-retry
|
|
88
|
+
*/
|
|
49
89
|
private createAxiosInstance;
|
|
90
|
+
/**
|
|
91
|
+
* 执行带特性的请求(重试、熔断器等)
|
|
92
|
+
*/
|
|
50
93
|
private executeWithFeatures;
|
|
94
|
+
/**
|
|
95
|
+
* 计算重试延迟
|
|
96
|
+
*/
|
|
51
97
|
private calculateRetryDelay;
|
|
98
|
+
/**
|
|
99
|
+
* 应用装饰器配置
|
|
100
|
+
*/
|
|
52
101
|
private applyDecoratorConfig;
|
|
102
|
+
/**
|
|
103
|
+
* 判断是否应该缓存请求
|
|
104
|
+
*/
|
|
53
105
|
private shouldCacheRequest;
|
|
106
|
+
/**
|
|
107
|
+
* 生成熔断器键
|
|
108
|
+
*/
|
|
54
109
|
private generateCircuitBreakerKey;
|
|
110
|
+
/**
|
|
111
|
+
* 更新请求统计
|
|
112
|
+
*/
|
|
55
113
|
private updateStats;
|
|
114
|
+
/**
|
|
115
|
+
* 更新错误统计
|
|
116
|
+
*/
|
|
56
117
|
private updateErrorStats;
|
|
118
|
+
/**
|
|
119
|
+
* 合并默认配置
|
|
120
|
+
*/
|
|
57
121
|
private mergeWithDefaults;
|
|
122
|
+
/**
|
|
123
|
+
* 深度合并对象
|
|
124
|
+
*/
|
|
58
125
|
private deepMerge;
|
|
59
126
|
}
|
|
60
127
|
export {};
|