@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.
- package/cache/cache.module.d.ts +0 -6
- package/cache/cache.module.js +7 -7
- package/cache/cache.service.js +12 -0
- package/cache/dependencies/db.dependency.d.ts +0 -13
- package/cache/dependencies/db.dependency.js +0 -16
- package/cache/dependencies/tag.dependency.d.ts +39 -4
- package/cache/dependencies/tag.dependency.js +109 -11
- package/cache/interfaces/cache-options.interface.d.ts +8 -0
- package/cache/providers/memory-cache.provider.d.ts +20 -0
- package/cache/providers/memory-cache.provider.js +40 -0
- package/http-client/config/http-client.config.d.ts +5 -0
- package/http-client/config/http-client.config.js +24 -13
- package/http-client/decorators/http-client.decorators.d.ts +1 -25
- package/http-client/decorators/http-client.decorators.js +97 -90
- package/http-client/entities/http-log.entity.d.ts +0 -20
- package/http-client/entities/http-log.entity.js +0 -12
- package/http-client/examples/advanced-usage.example.d.ts +4 -5
- package/http-client/examples/advanced-usage.example.js +4 -56
- package/http-client/http-client.module.d.ts +35 -2
- package/http-client/http-client.module.js +80 -75
- package/http-client/index.d.ts +1 -1
- package/http-client/interfaces/api-client-config.interface.d.ts +1 -91
- package/http-client/interfaces/http-client-config.interface.d.ts +53 -62
- package/http-client/services/api-client-registry.service.d.ts +5 -23
- package/http-client/services/api-client-registry.service.js +41 -284
- package/http-client/services/circuit-breaker.service.d.ts +69 -2
- package/http-client/services/circuit-breaker.service.js +185 -7
- package/http-client/services/http-client.service.d.ts +58 -23
- package/http-client/services/http-client.service.js +294 -150
- package/http-client/services/http-log-query.service.js +0 -13
- package/http-client/services/index.d.ts +0 -1
- package/http-client/services/index.js +0 -1
- package/http-client/services/logging.service.d.ts +79 -10
- package/http-client/services/logging.service.js +246 -51
- package/http-client/utils/call-stack-extractor.util.d.ts +26 -0
- package/http-client/utils/call-stack-extractor.util.js +35 -0
- package/http-client/utils/security-validator.util.d.ts +118 -0
- package/http-client/utils/security-validator.util.js +352 -0
- package/package.json +1 -1
- package/redis-lock/lock-heartbeat.service.d.ts +2 -0
- package/redis-lock/lock-heartbeat.service.js +12 -2
- package/redis-lock/redis-lock.service.d.ts +4 -0
- package/redis-lock/redis-lock.service.js +61 -8
- package/http-client/services/cache.service.d.ts +0 -76
- package/http-client/services/cache.service.js +0 -333
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HttpDecoratorUtils = exports.HttpUseProxy = exports.HttpTimeout = exports.HttpLogRequest = exports.
|
|
3
|
+
exports.HttpDecoratorUtils = exports.HttpUseProxy = exports.HttpTimeout = exports.HttpLogRequest = exports.HttpCircuitBreaker = exports.HttpRetry = exports.HttpClient = exports.CALL_INFO_KEY = exports.PROXY_OPTIONS_KEY = exports.TIMEOUT_OPTIONS_KEY = exports.LOGGING_OPTIONS_KEY = exports.CIRCUIT_BREAKER_OPTIONS_KEY = exports.RETRY_OPTIONS_KEY = exports.HTTP_CLIENT_OPTIONS_KEY = void 0;
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
|
-
const cache_options_interface_1 = require("../../cache/interfaces/cache-options.interface");
|
|
7
6
|
const call_stack_extractor_util_1 = require("../utils/call-stack-extractor.util");
|
|
8
7
|
// 装饰器元数据键
|
|
9
8
|
exports.HTTP_CLIENT_OPTIONS_KEY = 'http_client_options';
|
|
10
9
|
exports.RETRY_OPTIONS_KEY = 'http_retry_options';
|
|
11
10
|
exports.CIRCUIT_BREAKER_OPTIONS_KEY = 'http_circuit_breaker_options';
|
|
12
|
-
exports.CACHE_OPTIONS_KEY = 'http_cache_options';
|
|
13
11
|
exports.LOGGING_OPTIONS_KEY = 'http_logging_options';
|
|
14
12
|
exports.TIMEOUT_OPTIONS_KEY = 'http_timeout_options';
|
|
15
13
|
exports.PROXY_OPTIONS_KEY = 'http_proxy_options';
|
|
@@ -45,7 +43,29 @@ const HttpRetry = (options = {}) => {
|
|
|
45
43
|
shouldResetTimeout: options.shouldResetTimeout !== false,
|
|
46
44
|
onRetry: options.onRetry,
|
|
47
45
|
};
|
|
48
|
-
|
|
46
|
+
// Wrap the method to pass decorator context to HTTP client
|
|
47
|
+
const originalMethod = descriptor.value;
|
|
48
|
+
const wrappedMethod = function (...args) {
|
|
49
|
+
// Set decorator context (reference counting prevents overwriting)
|
|
50
|
+
call_stack_extractor_util_1.CallStackExtractor.setDecoratorContext({
|
|
51
|
+
target,
|
|
52
|
+
propertyKey,
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
return originalMethod.apply(this, args);
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
call_stack_extractor_util_1.CallStackExtractor.clearDecoratorContext();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
// Copy metadata from original to wrapped method
|
|
62
|
+
const metadataKeys = Reflect.getMetadataKeys(originalMethod);
|
|
63
|
+
for (const key of metadataKeys) {
|
|
64
|
+
Reflect.defineMetadata(key, Reflect.getMetadata(key, originalMethod), wrappedMethod);
|
|
65
|
+
}
|
|
66
|
+
// Store the retry options on the wrapped method
|
|
67
|
+
(0, common_1.SetMetadata)(`${exports.RETRY_OPTIONS_KEY}_${propertyKey}`, retryOptions)(wrappedMethod);
|
|
68
|
+
descriptor.value = wrappedMethod;
|
|
49
69
|
return descriptor;
|
|
50
70
|
};
|
|
51
71
|
};
|
|
@@ -64,74 +84,37 @@ const HttpCircuitBreaker = (options = {}) => {
|
|
|
64
84
|
minimumThroughputThreshold: options.minimumThroughputThreshold || 10,
|
|
65
85
|
countHalfOpenCalls: true,
|
|
66
86
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
? () => options.key
|
|
86
|
-
: undefined,
|
|
87
|
-
options: {
|
|
88
|
-
layers: (_a = options.layers) === null || _a === void 0 ? void 0 : _a.map((layer) => {
|
|
89
|
-
switch (layer) {
|
|
90
|
-
case 'cls':
|
|
91
|
-
return cache_options_interface_1.CacheLayer.CLS;
|
|
92
|
-
case 'memory':
|
|
93
|
-
return cache_options_interface_1.CacheLayer.MEMORY;
|
|
94
|
-
case 'redis':
|
|
95
|
-
return cache_options_interface_1.CacheLayer.REDIS;
|
|
96
|
-
default:
|
|
97
|
-
return cache_options_interface_1.CacheLayer.MEMORY;
|
|
98
|
-
}
|
|
99
|
-
}),
|
|
100
|
-
condition: options.condition,
|
|
101
|
-
prefix: options.namespace,
|
|
102
|
-
},
|
|
103
|
-
cacheableMethods: ['get'],
|
|
104
|
-
cacheableStatusCodes: [200, 201, 202, 204, 301, 302, 304],
|
|
87
|
+
// Wrap the method to pass decorator context to HTTP client
|
|
88
|
+
const originalMethod = descriptor.value;
|
|
89
|
+
const wrappedMethod = function (...args) {
|
|
90
|
+
// Store decorator context in async local storage or call stack
|
|
91
|
+
// Only set if not already set by another decorator
|
|
92
|
+
if (!call_stack_extractor_util_1.CallStackExtractor.getDecoratorContext()) {
|
|
93
|
+
call_stack_extractor_util_1.CallStackExtractor.setDecoratorContext({
|
|
94
|
+
target,
|
|
95
|
+
propertyKey,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
return originalMethod.apply(this, args);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
// Clean up the context after execution
|
|
103
|
+
call_stack_extractor_util_1.CallStackExtractor.clearDecoratorContext();
|
|
104
|
+
}
|
|
105
105
|
};
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const result = originalMethod.apply(this, args);
|
|
111
|
-
if (typeof options.unless === 'string') {
|
|
112
|
-
// 如果是字符串,作为表达式求值
|
|
113
|
-
if (evalInContext(options.unless, { result, args })) {
|
|
114
|
-
return result;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
else if (typeof options.unless === 'function') {
|
|
118
|
-
// 如果是函数,直接调用
|
|
119
|
-
if (options.unless(result, args)) {
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// 正常缓存
|
|
124
|
-
(0, common_1.SetMetadata)(`${exports.CACHE_OPTIONS_KEY}_${propertyKey}`, cacheOptions)(originalMethod);
|
|
125
|
-
return result;
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
(0, common_1.SetMetadata)(`${exports.CACHE_OPTIONS_KEY}_${propertyKey}`, cacheOptions)(descriptor.value);
|
|
106
|
+
// Copy metadata from original to wrapped method
|
|
107
|
+
const metadataKeys = Reflect.getMetadataKeys(originalMethod);
|
|
108
|
+
for (const key of metadataKeys) {
|
|
109
|
+
Reflect.defineMetadata(key, Reflect.getMetadata(key, originalMethod), wrappedMethod);
|
|
130
110
|
}
|
|
111
|
+
// Store the circuit breaker options on the wrapped method
|
|
112
|
+
(0, common_1.SetMetadata)(`${exports.CIRCUIT_BREAKER_OPTIONS_KEY}_${propertyKey}`, circuitBreakerOptions)(wrappedMethod);
|
|
113
|
+
descriptor.value = wrappedMethod;
|
|
131
114
|
return descriptor;
|
|
132
115
|
};
|
|
133
116
|
};
|
|
134
|
-
exports.
|
|
117
|
+
exports.HttpCircuitBreaker = HttpCircuitBreaker;
|
|
135
118
|
/**
|
|
136
119
|
* 请求日志装饰器
|
|
137
120
|
* 类似Spring Boot的@LogRequest注解
|
|
@@ -161,8 +144,30 @@ const HttpLogRequest = (options = {}) => {
|
|
|
161
144
|
methodName: options.methodName || decoratorInfo.methodName,
|
|
162
145
|
operationName: options.operationName || decoratorInfo.operationName,
|
|
163
146
|
};
|
|
164
|
-
|
|
165
|
-
|
|
147
|
+
// Wrap the method to pass decorator context to HTTP client
|
|
148
|
+
const originalMethod = descriptor.value;
|
|
149
|
+
const wrappedMethod = function (...args) {
|
|
150
|
+
// Set decorator context (reference counting prevents overwriting)
|
|
151
|
+
call_stack_extractor_util_1.CallStackExtractor.setDecoratorContext({
|
|
152
|
+
target,
|
|
153
|
+
propertyKey,
|
|
154
|
+
});
|
|
155
|
+
try {
|
|
156
|
+
return originalMethod.apply(this, args);
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
call_stack_extractor_util_1.CallStackExtractor.clearDecoratorContext();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
// Copy metadata from original to wrapped method
|
|
163
|
+
const metadataKeys = Reflect.getMetadataKeys(originalMethod);
|
|
164
|
+
for (const key of metadataKeys) {
|
|
165
|
+
Reflect.defineMetadata(key, Reflect.getMetadata(key, originalMethod), wrappedMethod);
|
|
166
|
+
}
|
|
167
|
+
// Store the logging options on the wrapped method
|
|
168
|
+
(0, common_1.SetMetadata)(`${exports.LOGGING_OPTIONS_KEY}_${propertyKey}`, loggingOptions)(wrappedMethod);
|
|
169
|
+
(0, common_1.SetMetadata)(`${exports.CALL_INFO_KEY}_${propertyKey}`, callInfo)(wrappedMethod);
|
|
170
|
+
descriptor.value = wrappedMethod;
|
|
166
171
|
return descriptor;
|
|
167
172
|
};
|
|
168
173
|
};
|
|
@@ -173,7 +178,29 @@ exports.HttpLogRequest = HttpLogRequest;
|
|
|
173
178
|
*/
|
|
174
179
|
const HttpTimeout = (timeoutMs) => {
|
|
175
180
|
return (target, propertyKey, descriptor) => {
|
|
176
|
-
|
|
181
|
+
// Wrap the method to pass decorator context to HTTP client
|
|
182
|
+
const originalMethod = descriptor.value;
|
|
183
|
+
const wrappedMethod = function (...args) {
|
|
184
|
+
// Set decorator context (reference counting prevents overwriting)
|
|
185
|
+
call_stack_extractor_util_1.CallStackExtractor.setDecoratorContext({
|
|
186
|
+
target,
|
|
187
|
+
propertyKey,
|
|
188
|
+
});
|
|
189
|
+
try {
|
|
190
|
+
return originalMethod.apply(this, args);
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
call_stack_extractor_util_1.CallStackExtractor.clearDecoratorContext();
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
// Copy metadata from original to wrapped method
|
|
197
|
+
const metadataKeys = Reflect.getMetadataKeys(originalMethod);
|
|
198
|
+
for (const key of metadataKeys) {
|
|
199
|
+
Reflect.defineMetadata(key, Reflect.getMetadata(key, originalMethod), wrappedMethod);
|
|
200
|
+
}
|
|
201
|
+
// Store the timeout options on the wrapped method
|
|
202
|
+
(0, common_1.SetMetadata)(`${exports.TIMEOUT_OPTIONS_KEY}_${propertyKey}`, timeoutMs)(wrappedMethod);
|
|
203
|
+
descriptor.value = wrappedMethod;
|
|
177
204
|
return descriptor;
|
|
178
205
|
};
|
|
179
206
|
};
|
|
@@ -205,12 +232,6 @@ class HttpDecoratorUtils {
|
|
|
205
232
|
static getCircuitBreakerOptions(target, propertyKey) {
|
|
206
233
|
return Reflect.getMetadata(`${exports.CIRCUIT_BREAKER_OPTIONS_KEY}_${propertyKey}`, target[propertyKey]);
|
|
207
234
|
}
|
|
208
|
-
/**
|
|
209
|
-
* 获取方法上的缓存配置
|
|
210
|
-
*/
|
|
211
|
-
static getCacheOptions(target, propertyKey) {
|
|
212
|
-
return Reflect.getMetadata(`${exports.CACHE_OPTIONS_KEY}_${propertyKey}`, target[propertyKey]);
|
|
213
|
-
}
|
|
214
235
|
/**
|
|
215
236
|
* 获取方法上的日志配置
|
|
216
237
|
*/
|
|
@@ -248,7 +269,6 @@ class HttpDecoratorUtils {
|
|
|
248
269
|
return {
|
|
249
270
|
retry: this.getRetryOptions(target, propertyKey),
|
|
250
271
|
circuitBreaker: this.getCircuitBreakerOptions(target, propertyKey),
|
|
251
|
-
cache: this.getCacheOptions(target, propertyKey),
|
|
252
272
|
logging: this.getLoggingOptions(target, propertyKey),
|
|
253
273
|
timeout: this.getTimeoutOptions(target, propertyKey),
|
|
254
274
|
proxy: this.getProxyOptions(target, propertyKey),
|
|
@@ -258,16 +278,3 @@ class HttpDecoratorUtils {
|
|
|
258
278
|
}
|
|
259
279
|
}
|
|
260
280
|
exports.HttpDecoratorUtils = HttpDecoratorUtils;
|
|
261
|
-
/**
|
|
262
|
-
* 在上下文中执行表达式
|
|
263
|
-
*/
|
|
264
|
-
function evalInContext(expression, context) {
|
|
265
|
-
try {
|
|
266
|
-
// 创建一个安全的执行环境
|
|
267
|
-
const func = new Function(...Object.keys(context), `return ${expression}`);
|
|
268
|
-
return func(...Object.values(context));
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
@@ -68,14 +68,6 @@ export declare class HttpLogEntity extends AbstractUuidPrimaryEntity {
|
|
|
68
68
|
* 响应体内容
|
|
69
69
|
*/
|
|
70
70
|
responseBody?: string;
|
|
71
|
-
/**
|
|
72
|
-
* 响应大小(字节)
|
|
73
|
-
*/
|
|
74
|
-
responseSize?: number;
|
|
75
|
-
/**
|
|
76
|
-
* 请求大小(字节)
|
|
77
|
-
*/
|
|
78
|
-
requestSize?: number;
|
|
79
71
|
/**
|
|
80
72
|
* 服务名称(用于微服务环境)
|
|
81
73
|
*/
|
|
@@ -104,10 +96,6 @@ export declare class HttpLogEntity extends AbstractUuidPrimaryEntity {
|
|
|
104
96
|
* 重试记录(JSON格式)
|
|
105
97
|
*/
|
|
106
98
|
retryRecords?: RetryRecord[];
|
|
107
|
-
/**
|
|
108
|
-
* 缓存命中状态
|
|
109
|
-
*/
|
|
110
|
-
cacheHit?: boolean;
|
|
111
99
|
/**
|
|
112
100
|
* 熔断器状态
|
|
113
101
|
*/
|
|
@@ -316,12 +304,4 @@ export interface HttpLogStats {
|
|
|
316
304
|
maxRetries: number;
|
|
317
305
|
retryRate: number;
|
|
318
306
|
};
|
|
319
|
-
/**
|
|
320
|
-
* 缓存统计
|
|
321
|
-
*/
|
|
322
|
-
cacheStats: {
|
|
323
|
-
cacheHits: number;
|
|
324
|
-
cacheMisses: number;
|
|
325
|
-
cacheHitRate: number;
|
|
326
|
-
};
|
|
327
307
|
}
|
|
@@ -83,14 +83,6 @@ __decorate([
|
|
|
83
83
|
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
84
84
|
__metadata("design:type", String)
|
|
85
85
|
], HttpLogEntity.prototype, "responseBody", void 0);
|
|
86
|
-
__decorate([
|
|
87
|
-
(0, typeorm_1.Column)({ type: 'int', nullable: true }),
|
|
88
|
-
__metadata("design:type", Number)
|
|
89
|
-
], HttpLogEntity.prototype, "responseSize", void 0);
|
|
90
|
-
__decorate([
|
|
91
|
-
(0, typeorm_1.Column)({ type: 'int', nullable: true }),
|
|
92
|
-
__metadata("design:type", Number)
|
|
93
|
-
], HttpLogEntity.prototype, "requestSize", void 0);
|
|
94
86
|
__decorate([
|
|
95
87
|
(0, typeorm_1.Column)({ type: 'varchar', length: 100, nullable: true }),
|
|
96
88
|
__metadata("design:type", String)
|
|
@@ -120,10 +112,6 @@ __decorate([
|
|
|
120
112
|
(0, typeorm_1.Column)({ type: 'json', nullable: true }),
|
|
121
113
|
__metadata("design:type", Array)
|
|
122
114
|
], HttpLogEntity.prototype, "retryRecords", void 0);
|
|
123
|
-
__decorate([
|
|
124
|
-
(0, typeorm_1.Column)({ type: 'boolean', nullable: true }),
|
|
125
|
-
__metadata("design:type", Boolean)
|
|
126
|
-
], HttpLogEntity.prototype, "cacheHit", void 0);
|
|
127
115
|
__decorate([
|
|
128
116
|
(0, typeorm_1.Column)({ type: 'varchar', length: 20, nullable: true }),
|
|
129
117
|
__metadata("design:type", String)
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { HttpClientService } from '../services/http-client.service';
|
|
2
2
|
/**
|
|
3
3
|
* 高级使用示例 - GitHub API客户端
|
|
4
|
-
* 集成现有的三层缓存架构
|
|
5
4
|
*/
|
|
6
5
|
export declare class GitHubHttpService {
|
|
7
6
|
private httpClient;
|
|
8
7
|
constructor(httpClient: HttpClientService);
|
|
9
8
|
/**
|
|
10
|
-
* 获取用户信息 -
|
|
9
|
+
* 获取用户信息 - 带重试、熔断器和日志
|
|
11
10
|
*/
|
|
12
11
|
getUser(username: string): Promise<any>;
|
|
13
12
|
/**
|
|
14
|
-
* 搜索仓库 -
|
|
13
|
+
* 搜索仓库 - 带重试
|
|
15
14
|
*/
|
|
16
15
|
searchRepositories(query: string, sort?: string, order?: string): Promise<any>;
|
|
17
16
|
/**
|
|
@@ -31,7 +30,7 @@ export declare class GitHubHttpService {
|
|
|
31
30
|
*/
|
|
32
31
|
getMultipleUsers(usernames: string[]): Promise<any[]>;
|
|
33
32
|
/**
|
|
34
|
-
*
|
|
33
|
+
* 获取仓库详情
|
|
35
34
|
*/
|
|
36
35
|
getRepositoryDetails(owner: string, repo: string, options?: {
|
|
37
36
|
public?: boolean;
|
|
@@ -49,7 +48,7 @@ export declare class PaymentHttpService {
|
|
|
49
48
|
*/
|
|
50
49
|
createPayment(paymentData: any, apiKey: string): Promise<any>;
|
|
51
50
|
/**
|
|
52
|
-
* 查询支付状态
|
|
51
|
+
* 查询支付状态
|
|
53
52
|
*/
|
|
54
53
|
getPaymentStatus(paymentId: string, apiKey: string): Promise<any>;
|
|
55
54
|
/**
|
|
@@ -22,17 +22,15 @@ exports.PaymentHttpService = exports.GitHubHttpService = void 0;
|
|
|
22
22
|
const common_1 = require("@nestjs/common");
|
|
23
23
|
const decorators_1 = require("../decorators");
|
|
24
24
|
const http_client_service_1 = require("../services/http-client.service");
|
|
25
|
-
const cache_options_interface_1 = require("../../cache/interfaces/cache-options.interface");
|
|
26
25
|
/**
|
|
27
26
|
* 高级使用示例 - GitHub API客户端
|
|
28
|
-
* 集成现有的三层缓存架构
|
|
29
27
|
*/
|
|
30
28
|
let GitHubHttpService = class GitHubHttpService {
|
|
31
29
|
constructor(httpClient) {
|
|
32
30
|
this.httpClient = httpClient;
|
|
33
31
|
}
|
|
34
32
|
/**
|
|
35
|
-
* 获取用户信息 -
|
|
33
|
+
* 获取用户信息 - 带重试、熔断器和日志
|
|
36
34
|
*/
|
|
37
35
|
getUser(username) {
|
|
38
36
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -40,7 +38,7 @@ let GitHubHttpService = class GitHubHttpService {
|
|
|
40
38
|
});
|
|
41
39
|
}
|
|
42
40
|
/**
|
|
43
|
-
* 搜索仓库 -
|
|
41
|
+
* 搜索仓库 - 带重试
|
|
44
42
|
*/
|
|
45
43
|
searchRepositories(query_1) {
|
|
46
44
|
return __awaiter(this, arguments, void 0, function* (query, sort = 'stars', order = 'desc') {
|
|
@@ -102,7 +100,7 @@ let GitHubHttpService = class GitHubHttpService {
|
|
|
102
100
|
});
|
|
103
101
|
}
|
|
104
102
|
/**
|
|
105
|
-
*
|
|
103
|
+
* 获取仓库详情
|
|
106
104
|
*/
|
|
107
105
|
getRepositoryDetails(owner, repo, options) {
|
|
108
106
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -126,11 +124,6 @@ __decorate([
|
|
|
126
124
|
failureThreshold: 3,
|
|
127
125
|
recoveryTimeoutMs: 30000,
|
|
128
126
|
}),
|
|
129
|
-
(0, decorators_1.HttpCacheable)({
|
|
130
|
-
ttl: 300000, // 5分钟缓存
|
|
131
|
-
layers: ['cls', 'memory', 'redis'], // 使用三层缓存
|
|
132
|
-
namespace: 'github',
|
|
133
|
-
}),
|
|
134
127
|
(0, decorators_1.HttpLogRequest)({
|
|
135
128
|
databaseLog: true,
|
|
136
129
|
logHeaders: true,
|
|
@@ -146,12 +139,6 @@ __decorate([
|
|
|
146
139
|
], GitHubHttpService.prototype, "getUser", null);
|
|
147
140
|
__decorate([
|
|
148
141
|
(0, decorators_1.HttpRetry)({ retries: 3 }),
|
|
149
|
-
(0, decorators_1.HttpCacheable)({
|
|
150
|
-
ttl: 600000, // 10分钟缓存
|
|
151
|
-
layers: ['memory', 'redis'], // 仅使用内存和Redis缓存
|
|
152
|
-
namespace: 'github-search',
|
|
153
|
-
condition: (args) => args[0].length > 2, // 只缓存搜索词长度大于2的请求
|
|
154
|
-
}),
|
|
155
142
|
__metadata("design:type", Function),
|
|
156
143
|
__metadata("design:paramtypes", [String, String, String]),
|
|
157
144
|
__metadata("design:returntype", Promise)
|
|
@@ -162,10 +149,6 @@ __decorate([
|
|
|
162
149
|
port: 8080,
|
|
163
150
|
protocol: 'http',
|
|
164
151
|
}),
|
|
165
|
-
(0, decorators_1.HttpCacheable)({
|
|
166
|
-
ttl: 120000, // 2分钟缓存
|
|
167
|
-
namespace: 'github-repos',
|
|
168
|
-
}),
|
|
169
152
|
__metadata("design:type", Function),
|
|
170
153
|
__metadata("design:paramtypes", [String]),
|
|
171
154
|
__metadata("design:returntype", Promise)
|
|
@@ -186,39 +169,14 @@ __decorate([
|
|
|
186
169
|
failureThreshold: 5,
|
|
187
170
|
recoveryTimeoutMs: 60000,
|
|
188
171
|
}),
|
|
189
|
-
(0, decorators_1.HttpCacheable)({
|
|
190
|
-
ttl: 900000, // 15分钟缓存
|
|
191
|
-
namespace: 'github-contributors',
|
|
192
|
-
}),
|
|
193
172
|
__metadata("design:type", Function),
|
|
194
173
|
__metadata("design:paramtypes", [String, String]),
|
|
195
174
|
__metadata("design:returntype", Promise)
|
|
196
175
|
], GitHubHttpService.prototype, "getRepositoryContributors", null);
|
|
197
|
-
__decorate([
|
|
198
|
-
(0, decorators_1.HttpCacheable)({
|
|
199
|
-
ttl: 120000, // 2分钟缓存
|
|
200
|
-
layers: ['memory'], // 仅内存缓存
|
|
201
|
-
namespace: 'github-repo-details',
|
|
202
|
-
condition: (args) => { var _a; return ((_a = args[2]) === null || _a === void 0 ? void 0 : _a.public) === true; }, // 只缓存公开仓库
|
|
203
|
-
unless: (result, args) => (result === null || result === void 0 ? void 0 : result.archived) === true, // 不缓存已归档的仓库
|
|
204
|
-
}),
|
|
205
|
-
__metadata("design:type", Function),
|
|
206
|
-
__metadata("design:paramtypes", [String, String, Object]),
|
|
207
|
-
__metadata("design:returntype", Promise)
|
|
208
|
-
], GitHubHttpService.prototype, "getRepositoryDetails", null);
|
|
209
176
|
exports.GitHubHttpService = GitHubHttpService = __decorate([
|
|
210
177
|
(0, decorators_1.HttpClient)({
|
|
211
178
|
baseURL: 'https://api.github.com',
|
|
212
179
|
timeout: 10000,
|
|
213
|
-
cache: {
|
|
214
|
-
enabled: true,
|
|
215
|
-
defaultTtl: 300000,
|
|
216
|
-
cacheableMethods: ['GET', 'HEAD'],
|
|
217
|
-
cacheableStatusCodes: [200, 304],
|
|
218
|
-
options: {
|
|
219
|
-
layers: [cache_options_interface_1.CacheLayer.MEMORY, cache_options_interface_1.CacheLayer.REDIS], // 使用现有的三层缓存
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
180
|
logging: {
|
|
223
181
|
enabled: true,
|
|
224
182
|
logRequests: true,
|
|
@@ -257,7 +215,7 @@ let PaymentHttpService = class PaymentHttpService {
|
|
|
257
215
|
});
|
|
258
216
|
}
|
|
259
217
|
/**
|
|
260
|
-
* 查询支付状态
|
|
218
|
+
* 查询支付状态
|
|
261
219
|
*/
|
|
262
220
|
getPaymentStatus(paymentId, apiKey) {
|
|
263
221
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -322,16 +280,6 @@ __decorate([
|
|
|
322
280
|
__metadata("design:paramtypes", [Object, String]),
|
|
323
281
|
__metadata("design:returntype", Promise)
|
|
324
282
|
], PaymentHttpService.prototype, "createPayment", null);
|
|
325
|
-
__decorate([
|
|
326
|
-
(0, decorators_1.HttpCacheable)({
|
|
327
|
-
ttl: 30000, // 30秒缓存
|
|
328
|
-
layers: ['redis'], // 仅Redis缓存,确保多实例共享
|
|
329
|
-
namespace: 'payment-status',
|
|
330
|
-
}),
|
|
331
|
-
__metadata("design:type", Function),
|
|
332
|
-
__metadata("design:paramtypes", [String, String]),
|
|
333
|
-
__metadata("design:returntype", Promise)
|
|
334
|
-
], PaymentHttpService.prototype, "getPaymentStatus", null);
|
|
335
283
|
__decorate([
|
|
336
284
|
(0, decorators_1.HttpRetry)({
|
|
337
285
|
retries: 2,
|
|
@@ -3,17 +3,50 @@ import { HttpClientConfig } from './interfaces/http-client-config.interface';
|
|
|
3
3
|
/**
|
|
4
4
|
* HTTP客户端模块
|
|
5
5
|
* 类似Spring Boot的自动配置机制,集成现有的cache服务
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // 最简单的方式 - 使用所有默认配置
|
|
9
|
+
* HttpClientModule.forRoot()
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // 只覆盖部分配置
|
|
13
|
+
* HttpClientModule.forRoot({
|
|
14
|
+
* baseURL: 'https://api.example.com',
|
|
15
|
+
* timeout: 5000,
|
|
16
|
+
* })
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // 深度合并配置
|
|
20
|
+
* HttpClientModule.forRoot({
|
|
21
|
+
* logging: {
|
|
22
|
+
* logLevel: 'debug',
|
|
23
|
+
* // 其他 logging 配置会使用默认值
|
|
24
|
+
* },
|
|
25
|
+
* })
|
|
6
26
|
*/
|
|
7
27
|
export declare class HttpClientModule {
|
|
8
28
|
/**
|
|
9
29
|
* 动态注册HTTP客户端模块
|
|
30
|
+
* @param config 用户配置,所有字段都是可选的
|
|
31
|
+
* @returns DynamicModule
|
|
10
32
|
*/
|
|
11
|
-
static forRoot(config?: HttpClientConfig): DynamicModule;
|
|
33
|
+
static forRoot(config?: Partial<HttpClientConfig>): DynamicModule;
|
|
12
34
|
/**
|
|
13
35
|
* 异步注册HTTP客户端模块
|
|
36
|
+
* @param config 异步配置,所有字段都是可选的
|
|
37
|
+
* @returns DynamicModule
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* HttpClientModule.forRootAsync({
|
|
41
|
+
* useFactory: (configService: ConfigService) => ({
|
|
42
|
+
* baseURL: configService.get('API_BASE_URL'),
|
|
43
|
+
* timeout: 5000,
|
|
44
|
+
* }),
|
|
45
|
+
* inject: [ConfigService],
|
|
46
|
+
* })
|
|
14
47
|
*/
|
|
15
48
|
static forRootAsync(config: {
|
|
16
|
-
useFactory: (...args: any[]) => Promise<HttpClientConfig
|
|
49
|
+
useFactory: (...args: any[]) => Promise<Partial<HttpClientConfig>> | Partial<HttpClientConfig>;
|
|
17
50
|
inject?: any[];
|
|
18
51
|
imports?: any[];
|
|
19
52
|
}): DynamicModule;
|