|
|
@@ -1,16 +1,14 @@
|
|
|
/**
|
|
|
- * 通用HTTP客户端主类
|
|
|
+ * 通用HTTP客户端主类 - 重构版本
|
|
|
*
|
|
|
- * 这是HTTP客户端库的核心类,提供跨平台的HTTP请求功能,
|
|
|
- * 支持多种认证方式、代理配置、性能监控和批量请求处理。
|
|
|
+ * 重构后的HTTP客户端,基于新的HttpClientCore架构,
|
|
|
+ * 提供向后兼容的API同时使用模块化的核心组件。
|
|
|
*
|
|
|
* 按照constitution要求,从libs/http-client迁移并模块化集成
|
|
|
*/
|
|
|
|
|
|
import { EventEmitter } from 'events'
|
|
|
|
|
|
-import { v4 as uuidv4 } from 'uuid'
|
|
|
-
|
|
|
import type {
|
|
|
HttpClientRequest,
|
|
|
HttpClientResponse,
|
|
|
@@ -21,13 +19,16 @@ import type {
|
|
|
OptimizationStats,
|
|
|
CacheStats,
|
|
|
ConnectionPoolStats,
|
|
|
- ResponseMetadata,
|
|
|
} from '@/types/httpClient'
|
|
|
-import type { PlatformConfig, IPlatformAdapter, PlatformRequest } from '@/types/platformAdapter'
|
|
|
+import type { PlatformConfig, IPlatformAdapter } from '@/types/platformAdapter'
|
|
|
+import type { IUniversalHttpClient, HealthStatus } from '@/types/httpClientCore'
|
|
|
|
|
|
+import { HttpClientCore } from '@/core/http-client/HttpClientCore'
|
|
|
+import { PlatformAdapterFactory } from '@/core/http-client/PlatformAdapterFactory'
|
|
|
+import { AccountRegistry, globalAccountRegistry } from '@/core/http-client/AccountRegistry'
|
|
|
import { HttpClient } from './httpClient'
|
|
|
|
|
|
-// 临时接口定义,后续将从其他模块迁移
|
|
|
+// Compatibility interfaces
|
|
|
interface PlatformRegistrationResult {
|
|
|
success: boolean
|
|
|
platformName: string
|
|
|
@@ -44,11 +45,10 @@ interface ProxyConfigurationResult {
|
|
|
error?: string
|
|
|
}
|
|
|
|
|
|
-export class UniversalHttpClient extends EventEmitter {
|
|
|
+export class UniversalHttpClient extends EventEmitter implements IUniversalHttpClient {
|
|
|
+ private readonly core: HttpClientCore
|
|
|
private readonly config: UniversalHttpClientConfig
|
|
|
- private readonly registeredPlatforms: Map<string, any> = new Map()
|
|
|
- private readonly requestCache: Map<string, any> = new Map()
|
|
|
- private readonly activeRequests: Map<string, Promise<any>> = new Map()
|
|
|
+ private readonly accountRegistry: AccountRegistry
|
|
|
private optimizationEnabled = false
|
|
|
private optimizationStats: OptimizationStats = {
|
|
|
totalOptimizations: 0,
|
|
|
@@ -58,296 +58,177 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
lastOptimization: new Date(),
|
|
|
}
|
|
|
|
|
|
- constructor(config: UniversalHttpClientConfig = {}) {
|
|
|
+ constructor(config: UniversalHttpClientConfig = {}, accountRegistry?: AccountRegistry) {
|
|
|
super()
|
|
|
this.config = config
|
|
|
+ this.accountRegistry = accountRegistry || globalAccountRegistry
|
|
|
+ this.core = new HttpClientCore(config, this.accountRegistry)
|
|
|
|
|
|
- // 设置事件监听
|
|
|
+ // Setup event forwarding from core to this instance
|
|
|
+ this.setupEventForwarding()
|
|
|
+
|
|
|
+ // Setup legacy event listeners
|
|
|
this.setupEventListeners()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行单个HTTP请求
|
|
|
+ * Setup event forwarding from core to this instance
|
|
|
*/
|
|
|
- async request<T = any>(request: HttpClientRequest): Promise<HttpClientResponse<T>> {
|
|
|
- const requestId = uuidv4()
|
|
|
- const startTime = Date.now()
|
|
|
-
|
|
|
- try {
|
|
|
- // 发出请求开始事件
|
|
|
- this.emit('request:start', {
|
|
|
- requestId,
|
|
|
- platform: request.platform,
|
|
|
- accountId: request.accountId,
|
|
|
- })
|
|
|
-
|
|
|
- // 获取平台适配器
|
|
|
- const adapter = this.getPlatformAdapter(request.platform)
|
|
|
- if (!adapter) {
|
|
|
- throw new Error(`Platform adapter not found: ${request.platform}`)
|
|
|
- }
|
|
|
-
|
|
|
- // 检查缓存
|
|
|
- const cacheKey = this.generateCacheKey(request)
|
|
|
- if (this.shouldUseCache(request) && this.requestCache.has(cacheKey)) {
|
|
|
- const cachedResponse = this.requestCache.get(cacheKey)
|
|
|
- if (this.isCacheValid(cachedResponse)) {
|
|
|
- this.emit('cache:hit', { requestId, key: cacheKey })
|
|
|
- return this.addMetadata(cachedResponse, requestId, request, startTime, true)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 应用代理配置
|
|
|
- const processedRequest = await this.applyProxyConfiguration(request)
|
|
|
-
|
|
|
- // 转换为平台请求格式
|
|
|
- const platformRequest: PlatformRequest = {
|
|
|
- accountId: processedRequest.accountId,
|
|
|
- method: processedRequest.method,
|
|
|
- path: new URL(processedRequest.url).pathname,
|
|
|
- headers: processedRequest.headers,
|
|
|
- body: processedRequest.body,
|
|
|
- params: undefined, // 从URL中提取查询参数
|
|
|
- options: {
|
|
|
- requiresAuth: true,
|
|
|
- timeout: processedRequest.options?.timeout?.read,
|
|
|
- enableRetry: !!processedRequest.options?.retry?.maxAttempts,
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- // 准备认证请求
|
|
|
- const authenticatedRequest = await adapter.prepareRequest(platformRequest)
|
|
|
-
|
|
|
- // 执行请求
|
|
|
- const platformResponse = await adapter.request(platformRequest)
|
|
|
-
|
|
|
- // 转换为通用HTTP响应格式
|
|
|
- const response: HttpClientResponse = {
|
|
|
- status: platformResponse.status,
|
|
|
- statusText: platformResponse.status >= 200 && platformResponse.status < 300 ? 'OK' : 'Error',
|
|
|
- ok: platformResponse.status >= 200 && platformResponse.status < 300,
|
|
|
- data: platformResponse.data,
|
|
|
- headers: platformResponse.headers,
|
|
|
- metadata: {
|
|
|
- requestId: uuidv4(),
|
|
|
- duration: 0,
|
|
|
- retryCount: 0,
|
|
|
- usedProxy: false,
|
|
|
- timestamp: new Date(),
|
|
|
- platform: request.platform,
|
|
|
- accountId: request.accountId,
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- // 合并平台元数据到通用元数据
|
|
|
- if (platformResponse.metadata) {
|
|
|
- response.metadata = {
|
|
|
- ...response.metadata,
|
|
|
- ...platformResponse.metadata,
|
|
|
- platform: platformResponse.metadata.platform,
|
|
|
- requestId: platformResponse.metadata.requestId,
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 缓存响应
|
|
|
- if (this.shouldCacheResponse(request, response)) {
|
|
|
- this.requestCache.set(cacheKey, response)
|
|
|
- this.emit('cache:miss', { requestId, key: cacheKey })
|
|
|
- }
|
|
|
-
|
|
|
- // 添加元数据
|
|
|
- const finalResponse = this.addMetadata(response, requestId, request, startTime, false)
|
|
|
-
|
|
|
- // 性能监控
|
|
|
- if (this.config.performanceMonitor) {
|
|
|
- // 性能监控记录 (待实现)
|
|
|
- }
|
|
|
-
|
|
|
- // 发出完成事件
|
|
|
- this.emit('request:complete', {
|
|
|
- requestId,
|
|
|
- duration: finalResponse.metadata.duration,
|
|
|
- success: true,
|
|
|
- })
|
|
|
-
|
|
|
- return finalResponse
|
|
|
- } catch (error) {
|
|
|
- const duration = Date.now() - startTime
|
|
|
-
|
|
|
- // 发出错误事件
|
|
|
- this.emit('request:error', { requestId, error })
|
|
|
+ private setupEventForwarding(): void {
|
|
|
+ // Forward core events to maintain compatibility
|
|
|
+ this.core.on('request:start', (data) => this.emit('request:start', data))
|
|
|
+ this.core.on('request:complete', (data) => this.emit('request:complete', data))
|
|
|
+ this.core.on('request:error', (data) => this.emit('request:error', data))
|
|
|
+ this.core.on('platform:registered', (data) => this.emit('platform:registered', data))
|
|
|
+ this.core.on('cache:hit', (data) => this.emit('cache:hit', data))
|
|
|
+ this.core.on('cache:miss', (data) => this.emit('cache:miss', data))
|
|
|
+ }
|
|
|
|
|
|
- // 性能监控错误记录
|
|
|
- if (this.config.performanceMonitor) {
|
|
|
- // 性能监控错误记录 (待实现)
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 执行单个HTTP请求 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ async request<T = any>(request: HttpClientRequest): Promise<HttpClientResponse<T>> {
|
|
|
+ // Delegate to core implementation
|
|
|
+ const response = await this.core.request<T>(request)
|
|
|
+
|
|
|
+ // Update optimization stats
|
|
|
+ this.updateOptimizationStats({
|
|
|
+ requestId: response.metadata.requestId,
|
|
|
+ duration: response.metadata.duration,
|
|
|
+ success: response.ok
|
|
|
+ })
|
|
|
|
|
|
- throw error
|
|
|
- }
|
|
|
+ return response
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 执行批量HTTP请求
|
|
|
+ * 执行批量HTTP请求 - 委托给HttpClientCore
|
|
|
*/
|
|
|
async batchRequest<T = any>(
|
|
|
requests: HttpClientRequest[],
|
|
|
options: BatchRequestOptions = {},
|
|
|
): Promise<BatchResult<T>> {
|
|
|
- const { concurrency = 10, failFast = false, retryFailedRequests = false, timeout = 30000 } = options
|
|
|
-
|
|
|
- const startTime = Date.now()
|
|
|
- const results: BatchResult<T>['results'] = []
|
|
|
+ // Delegate to core implementation
|
|
|
+ return this.core.batchRequest<T>(requests, options)
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 注册平台配置 - 兼容性方法
|
|
|
+ */
|
|
|
+ async registerPlatform(config: PlatformConfig): Promise<PlatformRegistrationResult>
|
|
|
+ async registerPlatform(platform: string, adapter: IPlatformAdapter): Promise<void>
|
|
|
+ async registerPlatform(
|
|
|
+ configOrPlatform: PlatformConfig | string,
|
|
|
+ adapter?: IPlatformAdapter
|
|
|
+ ): Promise<PlatformRegistrationResult | void> {
|
|
|
try {
|
|
|
- // 创建并发执行池
|
|
|
- const chunks = this.chunkArray(requests, concurrency)
|
|
|
-
|
|
|
- for (const chunk of chunks) {
|
|
|
- const chunkPromises = chunk.map(async (request, index) => {
|
|
|
- const globalIndex = chunks.indexOf(chunk) * concurrency + index
|
|
|
-
|
|
|
- try {
|
|
|
- const response = await this.request<T>(request)
|
|
|
- return {
|
|
|
- success: true,
|
|
|
- data: response.data,
|
|
|
- requestIndex: globalIndex,
|
|
|
- duration: response.metadata.duration,
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- if (failFast) {
|
|
|
- throw error
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- success: false,
|
|
|
- error,
|
|
|
- requestIndex: globalIndex,
|
|
|
- duration: Date.now() - startTime,
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // 等待当前批次完成
|
|
|
- const chunkResults = await Promise.all(chunkPromises)
|
|
|
- results.push(...chunkResults)
|
|
|
-
|
|
|
- // 检查是否需要提前终止
|
|
|
- if (failFast && chunkResults.some(r => !r.success)) {
|
|
|
- break
|
|
|
+ if (typeof configOrPlatform === 'string' && adapter) {
|
|
|
+ // New API: register platform with adapter directly
|
|
|
+ this.core.registerPlatform(configOrPlatform, adapter)
|
|
|
+ return
|
|
|
+ } else if (typeof configOrPlatform === 'object') {
|
|
|
+ // Legacy API: register platform with config
|
|
|
+ const config = configOrPlatform
|
|
|
+ this.validatePlatformConfig(config)
|
|
|
+
|
|
|
+ // Create platform adapter using factory
|
|
|
+ const createdAdapter = await this.createPlatformAdapter(config.platform, config)
|
|
|
+
|
|
|
+ // Register with core
|
|
|
+ this.core.registerPlatform(config.platform, createdAdapter)
|
|
|
+
|
|
|
+ return {
|
|
|
+ success: true,
|
|
|
+ platformName: config.platform,
|
|
|
+ adapter: createdAdapter,
|
|
|
}
|
|
|
+ } else {
|
|
|
+ throw new Error('Invalid arguments for registerPlatform')
|
|
|
}
|
|
|
-
|
|
|
- // 重试失败的请求
|
|
|
- if (retryFailedRequests) {
|
|
|
- const failedRequests = results.filter(r => !r.success).map(r => requests[r.requestIndex])
|
|
|
-
|
|
|
- if (failedRequests.length > 0) {
|
|
|
- const retryResults = await this.batchRequest(failedRequests, {
|
|
|
- ...options,
|
|
|
- retryFailedRequests: false,
|
|
|
- })
|
|
|
-
|
|
|
- // 更新失败的结果
|
|
|
- let retryIndex = 0
|
|
|
- for (let i = 0; i < results.length; i++) {
|
|
|
- if (!results[i].success) {
|
|
|
- results[i] = retryResults.results[retryIndex]
|
|
|
- retryIndex++
|
|
|
- }
|
|
|
- }
|
|
|
+ } catch (error) {
|
|
|
+ if (typeof configOrPlatform === 'object') {
|
|
|
+ return {
|
|
|
+ success: false,
|
|
|
+ platformName: configOrPlatform.platform,
|
|
|
+ error: error instanceof Error ? error.message : String(error),
|
|
|
}
|
|
|
}
|
|
|
+ throw error
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const totalDuration = Date.now() - startTime
|
|
|
- const successful = results.filter(r => r.success).length
|
|
|
- const failed = results.length - successful
|
|
|
-
|
|
|
- return {
|
|
|
- results,
|
|
|
- summary: {
|
|
|
- total: results.length,
|
|
|
- successful,
|
|
|
- failed,
|
|
|
- totalDuration,
|
|
|
- averageDuration: totalDuration / results.length,
|
|
|
- },
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- if (failFast) {
|
|
|
- throw error
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 获取客户端健康状态 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ async getHealth(): Promise<HealthStatus> {
|
|
|
+ return this.core.getHealth()
|
|
|
+ }
|
|
|
|
|
|
- // 返回部分结果
|
|
|
- const totalDuration = Date.now() - startTime
|
|
|
- const successful = results.filter(r => r.success).length
|
|
|
+ /**
|
|
|
+ * 关闭客户端并释放资源 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ async close(): Promise<void> {
|
|
|
+ return this.core.close()
|
|
|
+ }
|
|
|
|
|
|
- return {
|
|
|
- results,
|
|
|
- summary: {
|
|
|
- total: requests.length,
|
|
|
- successful,
|
|
|
- failed: requests.length - successful,
|
|
|
- totalDuration,
|
|
|
- averageDuration: results.length > 0 ? totalDuration / results.length : 0,
|
|
|
- },
|
|
|
- }
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 检查平台是否已注册 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ isPlatformRegistered(platform: string): boolean {
|
|
|
+ return this.core.isPlatformRegistered(platform)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 注册平台配置
|
|
|
+ * 获取平台适配器 - 委托给HttpClientCore
|
|
|
*/
|
|
|
- async registerPlatform(config: PlatformConfig): Promise<PlatformRegistrationResult> {
|
|
|
- try {
|
|
|
- // 验证配置
|
|
|
- this.validatePlatformConfig(config)
|
|
|
+ getPlatformAdapter(platform: string): IPlatformAdapter | undefined {
|
|
|
+ return this.core.getPlatformAdapter(platform)
|
|
|
+ }
|
|
|
|
|
|
- // 创建平台适配器 (待实现工厂模式)
|
|
|
- const adapter = await this.createPlatformAdapter(config.name, config)
|
|
|
+ /**
|
|
|
+ * 获取已注册平台列表 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ getRegisteredPlatforms(): string[] {
|
|
|
+ return this.core.getRegisteredPlatforms()
|
|
|
+ }
|
|
|
|
|
|
- // 注册平台
|
|
|
- this.registeredPlatforms.set(config.name, {
|
|
|
- config,
|
|
|
- adapter,
|
|
|
- })
|
|
|
+ /**
|
|
|
+ * 取消注册平台 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ async unregisterPlatform(platform: string): Promise<{ success: boolean }> {
|
|
|
+ return this.core.unregisterPlatform(platform)
|
|
|
+ }
|
|
|
|
|
|
- // 发出平台注册事件
|
|
|
- this.emit('platform:registered', { platform: config.name })
|
|
|
+ /**
|
|
|
+ * 更新平台配置 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ async updatePlatformConfig(platform: string, config: Partial<PlatformConfig>): Promise<{ success: boolean }> {
|
|
|
+ return this.core.updatePlatformConfig(platform, config)
|
|
|
+ }
|
|
|
|
|
|
- return {
|
|
|
- success: true,
|
|
|
- platformName: config.name,
|
|
|
- adapter,
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- return {
|
|
|
- success: false,
|
|
|
- platformName: config.name,
|
|
|
- error: error instanceof Error ? error.message : String(error),
|
|
|
- }
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 获取平台信息 - 委托给HttpClientCore
|
|
|
+ */
|
|
|
+ getPlatformInfo(platform: string): PlatformConfig | undefined {
|
|
|
+ return this.core.getPlatformInfo(platform)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 配置全局代理
|
|
|
+ * 配置全局代理 - 委托给HttpClientCore
|
|
|
*/
|
|
|
async configureGlobalProxy(config: any): Promise<ProxyConfigurationResult> {
|
|
|
try {
|
|
|
- // 验证代理配置
|
|
|
- this.validateProxyConfig(config)
|
|
|
+ const result = await this.core.configureGlobalProxy(config)
|
|
|
|
|
|
- // 配置代理 (待实现代理管理器)
|
|
|
- // await this.proxyManager.configureGlobalProxy(config);
|
|
|
-
|
|
|
- // 发出代理配置事件
|
|
|
+ // Emit event for compatibility
|
|
|
this.emit('proxy:configured', { type: 'global', config })
|
|
|
|
|
|
return {
|
|
|
- success: true,
|
|
|
- proxyUrl: this.buildProxyUrl(config),
|
|
|
- authConfigured: !!config.auth,
|
|
|
- customHeaders: !!config.headers,
|
|
|
+ success: result.success,
|
|
|
+ proxyUrl: result.proxyUrl,
|
|
|
+ authConfigured: result.authConfigured,
|
|
|
+ customHeaders: result.customHeaders,
|
|
|
+ error: result.error
|
|
|
}
|
|
|
} catch (error) {
|
|
|
return {
|
|
|
@@ -358,21 +239,22 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 配置账户专用代理
|
|
|
+ * 配置账户专用代理 - 委托给HttpClientCore
|
|
|
*/
|
|
|
async configureAccountProxy(accountId: string, config: any): Promise<ProxyConfigurationResult> {
|
|
|
try {
|
|
|
- this.validateProxyConfig(config)
|
|
|
- // await this.proxyManager.configureAccountProxy(accountId, config);
|
|
|
+ const result = await this.core.configureAccountProxy(accountId, config)
|
|
|
|
|
|
+ // Emit event for compatibility
|
|
|
this.emit('proxy:configured', { type: 'account', config })
|
|
|
|
|
|
return {
|
|
|
- success: true,
|
|
|
- accountId,
|
|
|
- proxyUrl: this.buildProxyUrl(config),
|
|
|
- authConfigured: !!config.auth,
|
|
|
- customHeaders: !!config.headers,
|
|
|
+ success: result.success,
|
|
|
+ accountId: result.accountId,
|
|
|
+ proxyUrl: result.proxyUrl,
|
|
|
+ authConfigured: result.authConfigured,
|
|
|
+ customHeaders: result.customHeaders,
|
|
|
+ error: result.error
|
|
|
}
|
|
|
} catch (error) {
|
|
|
return {
|
|
|
@@ -383,6 +265,41 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Account Management Methods
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Register account with credentials
|
|
|
+ */
|
|
|
+ registerAccount(
|
|
|
+ platform: string,
|
|
|
+ accountId: string,
|
|
|
+ credentials: any,
|
|
|
+ metadata?: { name?: string; description?: string }
|
|
|
+ ): void {
|
|
|
+ this.core.registerAccount(platform, accountId, credentials, metadata)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Check if account is registered
|
|
|
+ */
|
|
|
+ hasAccount(platform: string, accountId: string): boolean {
|
|
|
+ return this.core.hasAccount(platform, accountId)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get registered accounts
|
|
|
+ */
|
|
|
+ getRegisteredAccounts(): Array<{ platform: string; accountId: string; metadata?: any }> {
|
|
|
+ return this.core.getRegisteredAccounts()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get account registry (for advanced usage)
|
|
|
+ */
|
|
|
+ getAccountRegistry(): AccountRegistry {
|
|
|
+ return this.accountRegistry
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 启用性能优化
|
|
|
*/
|
|
|
@@ -453,65 +370,55 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
* 获取平台适配器
|
|
|
*/
|
|
|
getPlatformAdapter(platform: string): IPlatformAdapter | undefined {
|
|
|
- const platformData = this.registeredPlatforms.get(platform)
|
|
|
- return platformData?.adapter
|
|
|
+ return this.core.getPlatformAdapter(platform)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取已注册平台列表
|
|
|
*/
|
|
|
getRegisteredPlatforms(): string[] {
|
|
|
- return Array.from(this.registeredPlatforms.keys())
|
|
|
+ return this.core.getRegisteredPlatforms()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查平台是否已注册
|
|
|
*/
|
|
|
isPlatformRegistered(platform: string): boolean {
|
|
|
- return this.registeredPlatforms.has(platform)
|
|
|
+ return this.core.isPlatformRegistered(platform)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 取消注册平台
|
|
|
*/
|
|
|
async unregisterPlatform(platform: string): Promise<{ success: boolean }> {
|
|
|
- const existed = this.registeredPlatforms.delete(platform)
|
|
|
- return { success: existed }
|
|
|
+ return this.core.unregisterPlatform(platform)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 更新平台配置
|
|
|
*/
|
|
|
async updatePlatformConfig(platform: string, config: Partial<PlatformConfig>): Promise<{ success: boolean }> {
|
|
|
- const platformData = this.registeredPlatforms.get(platform)
|
|
|
- if (!platformData) {
|
|
|
- return { success: false }
|
|
|
- }
|
|
|
-
|
|
|
- // 更新配置
|
|
|
- platformData.config = { ...platformData.config, ...config }
|
|
|
- return { success: true }
|
|
|
+ return this.core.updatePlatformConfig(platform, config)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取平台信息
|
|
|
*/
|
|
|
getPlatformInfo(platform: string): PlatformConfig | undefined {
|
|
|
- const platformData = this.registeredPlatforms.get(platform)
|
|
|
- return platformData?.config
|
|
|
+ return this.core.getPlatformInfo(platform)
|
|
|
}
|
|
|
|
|
|
- // 私有辅助方法
|
|
|
+ // Private helper methods
|
|
|
|
|
|
private setupEventListeners(): void {
|
|
|
- // 设置内部事件监听器
|
|
|
+ // Setup internal event listeners for legacy compatibility
|
|
|
this.on('request:complete', data => {
|
|
|
this.updateOptimizationStats(data)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
private validatePlatformConfig(config: PlatformConfig): void {
|
|
|
- if (!config.name || !config.baseUrl || !config.authConfig?.type) {
|
|
|
+ if (!config.platform || !config.baseUrl || !config.authConfig?.type) {
|
|
|
throw new Error('Invalid platform configuration: missing required fields')
|
|
|
}
|
|
|
|
|
|
@@ -521,102 +428,59 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private validateProxyConfig(config: any): void {
|
|
|
- if (!config.enabled) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if (!config.url && (!config.host || !config.port)) {
|
|
|
- throw new Error('Invalid proxy configuration: missing URL or host/port')
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private buildProxyUrl(config: any): string {
|
|
|
- if (config.url) {
|
|
|
- return config.url
|
|
|
- }
|
|
|
-
|
|
|
- const protocol = config.protocol || 'http'
|
|
|
- const auth = config.auth ? `${config.auth.username}:${config.auth.password}@` : ''
|
|
|
- return `${protocol}://${auth}${config.host}:${config.port}`
|
|
|
- }
|
|
|
-
|
|
|
- private generateCacheKey(request: HttpClientRequest): string {
|
|
|
- const key = `${request.platform}:${request.method}:${request.url}:${JSON.stringify(request.body || {})}`
|
|
|
- return Buffer.from(key).toString('base64')
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * Create platform adapter using factory - implements T026
|
|
|
+ */
|
|
|
+ private async createPlatformAdapter(platform: string, config: PlatformConfig): Promise<IPlatformAdapter> {
|
|
|
+ try {
|
|
|
+ // Ensure adapters are registered with factory
|
|
|
+ this.ensureAdaptersRegistered()
|
|
|
|
|
|
- private shouldUseCache(request: HttpClientRequest): boolean {
|
|
|
- return !!(this.config.cache?.enabled && request.options?.cache?.enabled && request.method === 'GET')
|
|
|
- }
|
|
|
+ // Create adapter using PlatformAdapterFactory
|
|
|
+ const adapter = PlatformAdapterFactory.createAdapter(platform, config)
|
|
|
|
|
|
- private shouldCacheResponse(request: HttpClientRequest, response: HttpClientResponse): boolean {
|
|
|
- return !!(this.shouldUseCache(request) && response.ok && response.status < 400)
|
|
|
- }
|
|
|
+ // Set up credential manager if available
|
|
|
+ if (this.config.credentialManager) {
|
|
|
+ adapter.setCredentialManager?.(this.config.credentialManager)
|
|
|
+ }
|
|
|
|
|
|
- private isCacheValid(cachedResponse: any): boolean {
|
|
|
- if (!cachedResponse.metadata.cachedAt) {
|
|
|
- return false
|
|
|
+ return adapter
|
|
|
+ } catch (error) {
|
|
|
+ throw new Error(`Failed to create platform adapter for ${platform}: ${error instanceof Error ? error.message : String(error)}`)
|
|
|
}
|
|
|
-
|
|
|
- const ttl = this.config.cache?.ttl || 300000 // 5分钟默认
|
|
|
- const age = Date.now() - cachedResponse.metadata.cachedAt
|
|
|
- return age < ttl
|
|
|
}
|
|
|
|
|
|
- private async applyProxyConfiguration(request: HttpClientRequest): Promise<HttpClientRequest> {
|
|
|
- if (!request.options?.proxy?.enabled) {
|
|
|
- return request
|
|
|
- }
|
|
|
-
|
|
|
- // 应用代理逻辑 (待实现代理管理器)
|
|
|
- // const proxyConfig = await this.proxyManager.getProxyForRequest(request);
|
|
|
-
|
|
|
- return {
|
|
|
- ...request,
|
|
|
- options: {
|
|
|
- ...request.options,
|
|
|
- // proxy: proxyConfig
|
|
|
- },
|
|
|
+ /**
|
|
|
+ * Ensure platform adapters are registered with the factory
|
|
|
+ */
|
|
|
+ private ensureAdaptersRegistered(): void {
|
|
|
+ // Register adapters if not already registered
|
|
|
+ if (!PlatformAdapterFactory.isAdapterRegistered('pacifica')) {
|
|
|
+ // Dynamic import to avoid circular dependencies
|
|
|
+ import('@/adapters/pacifica/PacificaHttpAdapter').then(({ PacificaHttpAdapter }) => {
|
|
|
+ PlatformAdapterFactory.registerAdapter('pacifica', PacificaHttpAdapter)
|
|
|
+ }).catch(() => {
|
|
|
+ // Fallback - adapter may not be available
|
|
|
+ })
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- private addMetadata<T>(
|
|
|
- response: HttpClientResponse<T>,
|
|
|
- requestId: string,
|
|
|
- request: HttpClientRequest,
|
|
|
- startTime: number,
|
|
|
- cacheHit: boolean,
|
|
|
- ): HttpClientResponse<T> {
|
|
|
- const duration = Date.now() - startTime
|
|
|
-
|
|
|
- const metadata: ResponseMetadata = {
|
|
|
- requestId,
|
|
|
- duration,
|
|
|
- retryCount: 0,
|
|
|
- usedProxy: !!request.options?.proxy?.enabled,
|
|
|
- timestamp: new Date(),
|
|
|
- platform: request.platform,
|
|
|
- accountId: request.accountId,
|
|
|
- cacheHit,
|
|
|
- networkLatency: duration * 0.7, // 估算网络延迟
|
|
|
- processingTime: duration * 0.3, // 估算处理时间
|
|
|
- responseSize: JSON.stringify(response.data).length,
|
|
|
+ if (!PlatformAdapterFactory.isAdapterRegistered('binance')) {
|
|
|
+ import('@/adapters/binance/BinanceHttpAdapter').then(({ BinanceHttpAdapter }) => {
|
|
|
+ PlatformAdapterFactory.registerAdapter('binance', BinanceHttpAdapter)
|
|
|
+ }).catch(() => {
|
|
|
+ // Fallback - adapter may not be available
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
- return {
|
|
|
- ...response,
|
|
|
- metadata: { ...response.metadata, ...metadata },
|
|
|
+ if (!PlatformAdapterFactory.isAdapterRegistered('aster')) {
|
|
|
+ import('@/adapters/aster/AsterHttpAdapter').then(({ AsterHttpAdapter }) => {
|
|
|
+ PlatformAdapterFactory.registerAdapter('aster', AsterHttpAdapter)
|
|
|
+ }).catch(() => {
|
|
|
+ // Fallback - adapter may not be available
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private chunkArray<T>(array: T[], chunkSize: number): T[][] {
|
|
|
- const chunks: T[][] = []
|
|
|
- for (let i = 0; i < array.length; i += chunkSize) {
|
|
|
- chunks.push(array.slice(i, i + chunkSize))
|
|
|
- }
|
|
|
- return chunks
|
|
|
- }
|
|
|
|
|
|
private updateOptimizationStats(data: any): void {
|
|
|
this.optimizationStats.totalOptimizations++
|
|
|
@@ -627,12 +491,6 @@ export class UniversalHttpClient extends EventEmitter {
|
|
|
|
|
|
this.optimizationStats.lastOptimization = new Date()
|
|
|
}
|
|
|
-
|
|
|
- // 临时实现,待迁移平台适配器工厂
|
|
|
- private async createPlatformAdapter(platform: string, config: PlatformConfig): Promise<IPlatformAdapter> {
|
|
|
- // 这将在后续迁移平台适配器时实现
|
|
|
- throw new Error(`Platform adapter factory not yet implemented for ${platform}`)
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
// 重新导出类型定义,从本地类型文件导入
|
|
|
@@ -654,12 +512,6 @@ export type {
|
|
|
|
|
|
export type { PlatformConfig, IPlatformAdapter, PlatformRequest, PlatformResponse } from '@/types/platformAdapter'
|
|
|
|
|
|
-/**
|
|
|
- * 创建统一HTTP客户端实例
|
|
|
- */
|
|
|
-export function createUniversalHttpClient(config: UniversalHttpClientConfig = {}): UniversalHttpClient {
|
|
|
- return new UniversalHttpClient(config)
|
|
|
-}
|
|
|
|
|
|
/**
|
|
|
* HttpClientAdapter - 适配现有HttpClient到新的UniversalHttpClient
|
|
|
@@ -813,3 +665,35 @@ export async function pacificaApiCall<T = any>(
|
|
|
throw new Error(`Pacifica API call failed: ${error instanceof Error ? error.message : String(error)}`)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Create Universal HTTP Client with optional AccountRegistry
|
|
|
+ */
|
|
|
+export function createUniversalHttpClient(
|
|
|
+ config: UniversalHttpClientConfig = {},
|
|
|
+ accountRegistry?: AccountRegistry
|
|
|
+): UniversalHttpClient {
|
|
|
+ return new UniversalHttpClient(config, accountRegistry)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Create Universal HTTP Client with accounts pre-configured
|
|
|
+ */
|
|
|
+export function createUniversalHttpClientWithAccounts(
|
|
|
+ config: UniversalHttpClientConfig = {},
|
|
|
+ accounts: Array<{
|
|
|
+ platform: string
|
|
|
+ accountId: string
|
|
|
+ credentials: any
|
|
|
+ metadata?: { name?: string; description?: string }
|
|
|
+ }> = []
|
|
|
+): UniversalHttpClient {
|
|
|
+ const client = new UniversalHttpClient(config)
|
|
|
+
|
|
|
+ // Register all accounts
|
|
|
+ accounts.forEach(account => {
|
|
|
+ client.registerAccount(account.platform, account.accountId, account.credentials, account.metadata)
|
|
|
+ })
|
|
|
+
|
|
|
+ return client
|
|
|
+}
|