@djvlc/openapi-client-core 1.1.0 → 1.2.0

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/dist/index.d.ts CHANGED
@@ -1,996 +1,274 @@
1
- /**
2
- * @djvlc/openapi-client-core - 版本信息
3
- *
4
- * 版本号在构建时由 tsup 注入,避免手动维护。
5
- */
6
- /**
7
- * SDK 版本号(构建时注入)
8
- */
9
- declare const SDK_VERSION: string;
10
- /**
11
- * SDK 名称(构建时注入)
12
- */
13
- declare const SDK_NAME: string;
14
- /**
15
- * 获取 SDK 版本信息
16
- */
17
- declare function getSdkInfo(): {
18
- name: string;
19
- version: string;
20
- };
1
+ import { ErrorCode, ApiErrorResponse, RequestContext, ApiSuccessResponse } from '@djvlc/contracts-types';
2
+ import { AxiosInstance } from 'axios';
3
+ export { AxiosError, AxiosInstance, InternalAxiosRequestConfig } from 'axios';
21
4
 
22
5
  /**
23
- * @djvlc/openapi-client-core - 错误类定义
24
- *
25
- * 提供结构化的错误类型,便于调用方区分和处理不同类型的错误。
26
- *
27
- * 错误层次:
28
- * - DjvApiError: 业务层错误(服务器返回的错误响应)
29
- * - NetworkError: 网络层错误(连接失败、DNS 解析失败等)
30
- * - TimeoutError: 超时错误(继承自 NetworkError)
31
- * - AbortError: 请求被取消(继承自 NetworkError)
6
+ * 错误类型定义
32
7
  */
8
+
33
9
  /**
34
- * API 业务错误
35
- *
36
- * 当服务器返回非 2xx 响应时抛出,包含完整的错误信息。
37
- *
38
- * @example
39
- * ```typescript
40
- * try {
41
- * await client.PageApi.resolvePage({ pageUid: 'xxx' });
42
- * } catch (e) {
43
- * if (DjvApiError.is(e)) {
44
- * console.log('业务错误:', e.code, e.message);
45
- * console.log('追踪ID:', e.traceId);
46
- *
47
- * // 使用增强方法
48
- * if (e.isAuthError()) {
49
- * redirectToLogin();
50
- * } else if (e.isRateLimited()) {
51
- * const retryAfter = e.getRetryAfter();
52
- * await delay(retryAfter * 1000);
53
- * }
54
- * }
55
- * }
56
- * ```
10
+ * API 错误
57
11
  */
58
- declare class DjvApiError extends Error {
59
- /** 业务错误码(可能是字符串如 'INVALID_REQUEST' 或数字如 1001) */
60
- readonly code: string | number;
12
+ declare class ApiError extends Error {
13
+ /** 错误码 */
14
+ readonly code: ErrorCode | string;
61
15
  /** HTTP 状态码 */
62
- readonly status: number;
63
- /** 追踪 ID(用于日志排查) */
64
- readonly traceId?: string | undefined;
65
- /** 详细错误信息(字段级错误等) */
66
- readonly details?: unknown | undefined;
67
- /** 原始响应对象 */
68
- readonly response?: Response | undefined;
69
- /** 标识这是一个 API 错误(用于 instanceof 替代方案) */
70
- readonly isApiError: true;
71
- /** 错误名称 */
72
- readonly name: "DjvApiError";
73
- constructor(message: string,
74
- /** 业务错误码(可能是字符串如 'INVALID_REQUEST' 或数字如 1001) */
75
- code: string | number,
76
- /** HTTP 状态码 */
77
- status: number,
78
- /** 追踪 ID(用于日志排查) */
79
- traceId?: string | undefined,
80
- /** 详细错误信息(字段级错误等) */
81
- details?: unknown | undefined,
82
- /** 原始响应对象 */
83
- response?: Response | undefined);
84
- /**
85
- * 是否为认证错误 (401 Unauthorized)
86
- */
87
- isUnauthorized(): boolean;
88
- /**
89
- * 是否为权限错误 (403 Forbidden)
90
- */
91
- isForbidden(): boolean;
92
- /**
93
- * 是否为认证相关错误 (401 或 403)
94
- */
95
- isAuthError(): boolean;
96
- /**
97
- * 是否为客户端错误 (4xx)
98
- */
99
- isClientError(): boolean;
100
- /**
101
- * 是否为服务端错误 (5xx)
102
- */
103
- isServerError(): boolean;
104
- /**
105
- * 是否为限流错误 (429 Too Many Requests)
106
- */
107
- isRateLimited(): boolean;
108
- /**
109
- * 是否为资源未找到 (404 Not Found)
110
- */
111
- isNotFound(): boolean;
112
- /**
113
- * 是否为请求冲突 (409 Conflict)
114
- */
115
- isConflict(): boolean;
116
- /**
117
- * 是否为请求验证失败 (400 Bad Request 或 422 Unprocessable Entity)
118
- */
119
- isValidationError(): boolean;
120
- /**
121
- * 获取 Retry-After 头的值(秒)
122
- *
123
- * 适用于 429 限流响应和 503 服务不可用响应
124
- *
125
- * @returns 重试等待秒数,如果没有 Retry-After 头则返回 null
126
- */
127
- getRetryAfter(): number | null;
128
- /**
129
- * 获取重试延迟(毫秒)
130
- *
131
- * 优先使用 Retry-After 头,否则返回默认值
132
- *
133
- * @param defaultMs 默认延迟毫秒数
134
- */
135
- getRetryDelayMs(defaultMs?: number): number;
136
- /**
137
- * 类型保护:判断是否为 DjvApiError
138
- */
139
- static is(error: unknown): error is DjvApiError;
140
- /**
141
- * 从响应创建错误
142
- */
143
- static fromResponse(response: Response): Promise<DjvApiError>;
144
- /**
145
- * 转为 JSON(便于日志记录)
146
- */
147
- toJSON(): {
148
- name: "DjvApiError";
16
+ readonly statusCode: number;
17
+ /** 错误详情 */
18
+ readonly details?: {
19
+ field?: string;
149
20
  message: string;
150
- code: string | number;
151
- status: number;
152
- traceId: string | undefined;
153
- details: unknown;
154
- };
21
+ code?: string;
22
+ }[];
23
+ /** 请求 ID */
24
+ readonly requestId: string;
25
+ /** 链路追踪 ID */
26
+ readonly traceId?: string;
27
+ /** 是否可重试 */
28
+ readonly retryable: boolean;
29
+ constructor(response: ApiErrorResponse, statusCode: number);
30
+ private isRetryable;
155
31
  }
156
32
  /**
157
- * 网络层错误
158
- *
159
- * 当请求无法到达服务器时抛出(连接失败、DNS 解析失败、CORS 等)。
160
- *
161
- * @example
162
- * ```typescript
163
- * try {
164
- * await client.PageApi.resolvePage({ pageUid: 'xxx' });
165
- * } catch (e) {
166
- * if (NetworkError.is(e)) {
167
- * console.log('网络错误,请检查网络连接');
168
- * }
169
- * }
170
- * ```
33
+ * 网络错误
171
34
  */
172
35
  declare class NetworkError extends Error {
173
- /** 标识这是一个网络错误 */
174
- readonly isNetworkError: true;
175
- /** 错误名称 */
176
- readonly name: string;
177
- /** 原始错误 */
178
- readonly originalCause?: Error;
179
- constructor(message: string,
180
- /** 原始错误 */
181
- cause?: Error);
182
- /**
183
- * 获取原始错误
184
- */
185
- get cause(): Error | undefined;
186
- /**
187
- * 类型保护:判断是否为 NetworkError(包括子类)
188
- */
189
- static is(error: unknown): error is NetworkError;
190
- /**
191
- * 从原始错误创建
192
- */
193
- static fromError(error: unknown): NetworkError | AbortError;
194
- toJSON(): Record<string, unknown>;
36
+ readonly cause?: Error | undefined;
37
+ readonly retryable = true;
38
+ constructor(message: string, cause?: Error | undefined);
195
39
  }
196
40
  /**
197
41
  * 超时错误
198
- *
199
- * 当请求超过指定时间未响应时抛出。
200
- *
201
- * @example
202
- * ```typescript
203
- * try {
204
- * await client.PageApi.resolvePage({ pageUid: 'xxx' });
205
- * } catch (e) {
206
- * if (TimeoutError.is(e)) {
207
- * console.log(`请求超时 (${e.timeoutMs}ms),请稍后重试`);
208
- * }
209
- * }
210
- * ```
211
42
  */
212
- declare class TimeoutError extends NetworkError {
213
- /** 超时时间(毫秒) */
214
- readonly timeoutMs: number;
215
- /** 请求 URL */
216
- readonly url?: string | undefined;
217
- /** 标识这是一个超时错误 */
218
- readonly isTimeout: true;
219
- readonly name: string;
220
- constructor(
221
- /** 超时时间(毫秒) */
222
- timeoutMs: number,
223
- /** 请求 URL */
224
- url?: string | undefined);
225
- /**
226
- * 类型保护:判断是否为 TimeoutError
227
- */
228
- static is(error: unknown): error is TimeoutError;
229
- toJSON(): Record<string, unknown>;
43
+ declare class TimeoutError extends Error {
44
+ readonly retryable = true;
45
+ constructor(timeout: number);
230
46
  }
231
- /**
232
- * 请求取消错误
233
- *
234
- * 当请求被用户手动取消时抛出。
235
- *
236
- * @example
237
- * ```typescript
238
- * const controller = new AbortController();
239
- * setTimeout(() => controller.abort(), 100);
240
- *
241
- * try {
242
- * await client.PageApi.resolvePage({ pageUid: 'xxx' }, { signal: controller.signal });
243
- * } catch (e) {
244
- * if (AbortError.is(e)) {
245
- * console.log('请求已取消');
246
- * }
247
- * }
248
- * ```
249
- */
250
- declare class AbortError extends NetworkError {
251
- /** 标识这是一个取消错误 */
252
- readonly isAbort: true;
253
- readonly name: string;
254
- constructor(message?: string);
255
- /**
256
- * 类型保护:判断是否为 AbortError
257
- */
258
- static is(error: unknown): error is AbortError;
259
- }
260
- /**
261
- * 判断错误是否可重试
262
- *
263
- * 可重试的情况:
264
- * - 超时错误
265
- * - 网络错误(非取消)
266
- * - 特定 HTTP 状态码:408, 429, 500, 502, 503, 504
267
- */
268
- declare function isRetryableError(error: unknown): boolean;
269
- /**
270
- * 获取错误的推荐重试延迟(毫秒)
271
- *
272
- * 优先使用 Retry-After 头,否则返回默认值
273
- */
274
- declare function getRetryDelay(error: unknown, defaultMs?: number): number;
275
47
 
276
48
  /**
277
- * @djvlc/openapi-client-core - 公共类型定义
278
- */
279
- /**
280
- * 请求上下文(Middleware 使用)
281
- */
282
- interface RequestContext {
283
- /** 请求 URL */
284
- url: string;
285
- /** 请求初始化配置 */
286
- init: RequestInit;
287
- /** 额外元数据 */
288
- meta?: Record<string, unknown>;
289
- }
290
- /**
291
- * 响应上下文(Middleware 使用)
292
- */
293
- interface ResponseContext extends RequestContext {
294
- /** 响应对象 */
295
- response: Response;
296
- /** 请求耗时(毫秒) */
297
- durationMs: number;
298
- }
299
- /**
300
- * Middleware 定义
301
- */
302
- interface Middleware {
303
- /** 请求前钩子 */
304
- pre?: (context: RequestContext) => Promise<RequestContext> | RequestContext;
305
- /** 响应后钩子 */
306
- post?: (context: ResponseContext) => Promise<void> | void;
307
- }
308
- /**
309
- * 重试配置
310
- */
311
- interface RetryOptions {
312
- /** 最大重试次数(默认 0 不重试) */
313
- maxRetries?: number;
314
- /** 重试延迟基数(毫秒,默认 1000) */
315
- retryDelayMs?: number;
316
- /** 是否使用指数退避(默认 true) */
317
- exponentialBackoff?: boolean;
318
- /** 最大延迟时间(毫秒,默认 30000) */
319
- maxDelayMs?: number;
320
- /** 可重试的 HTTP 状态码(默认 [408, 429, 500, 502, 503, 504]) */
321
- retryableStatuses?: number[];
322
- /** 自定义重试判断函数 */
323
- shouldRetry?: (error: unknown, attempt: number) => boolean;
324
- /** 重试前回调(用于日志等) */
325
- onRetry?: (error: unknown, attempt: number, delayMs: number) => void;
326
- /**
327
- * 是否尊重 Retry-After 响应头
328
- *
329
- * 当服务器返回 429 或 503 时,优先使用 Retry-After 头中的延迟时间
330
- *
331
- * @default true
332
- */
333
- respectRetryAfter?: boolean;
334
- }
335
- /**
336
- * 日志接口
337
- */
338
- interface Logger {
339
- /** 请求日志 */
340
- request?: (url: string, init: RequestInit) => void;
341
- /** 响应日志 */
342
- response?: (url: string, response: Response, durationMs: number) => void;
343
- /** 错误日志 */
344
- error?: (url: string, error: unknown) => void;
345
- /** 重试日志 */
346
- retry?: (url: string, attempt: number, error: unknown) => void;
347
- }
348
- /**
349
- * 拦截器配置
350
- */
351
- interface Interceptors {
352
- /** 请求拦截器 */
353
- request?: RequestInterceptor[];
354
- /** 响应拦截器 */
355
- response?: ResponseInterceptor[];
356
- /** 错误拦截器 */
357
- error?: ErrorInterceptor[];
358
- }
359
- /**
360
- * 请求拦截器
361
- */
362
- type RequestInterceptor = (context: RequestContext) => Promise<RequestContext> | RequestContext;
363
- /**
364
- * 响应拦截器
49
+ * 客户端配置和类型定义
365
50
  */
366
- type ResponseInterceptor = (response: Response, context: RequestContext) => Promise<Response> | Response;
367
- /**
368
- * 错误拦截器
369
- */
370
- type ErrorInterceptor = (error: unknown, context: RequestContext) => Promise<unknown> | unknown;
51
+
371
52
  /**
372
- * 基础客户端配置
53
+ * 客户端配置
373
54
  */
374
- interface BaseClientOptions {
55
+ interface ClientConfig {
375
56
  /** 基础 URL */
376
57
  baseUrl: string;
377
- /** 获取认证 Token(Bearer) */
378
- getAuthToken?: () => string | Promise<string>;
379
- /** 获取 API Key */
380
- getApiKey?: () => string | Promise<string>;
381
- /** 获取追踪头(OpenTelemetry) */
382
- getTraceHeaders?: () => Record<string, string>;
58
+ /** 默认超时时间(毫秒) */
59
+ timeout?: number;
383
60
  /** 默认请求头 */
384
- defaultHeaders?: Record<string, string>;
385
- /** 超时时间(毫秒,默认 30000) */
386
- timeoutMs?: number;
387
- /** 自定义 fetch 实现 */
388
- fetchApi?: typeof fetch;
389
- /** Cookie 策略(默认 'omit') */
390
- credentials?: RequestCredentials;
61
+ headers?: Record<string, string>;
62
+ /** 认证配置 */
63
+ auth?: AuthConfig;
391
64
  /** 重试配置 */
392
- retry?: RetryOptions;
393
- /** 日志配置 */
394
- logger?: Logger;
395
- /** 是否开启调试模式 */
396
- debug?: boolean;
397
- /** Middleware 列表 */
398
- middleware?: Middleware[];
399
- /** 拦截器 */
400
- interceptors?: Interceptors;
65
+ retry?: RetryConfig;
66
+ /** 请求拦截器 */
67
+ onRequest?: RequestInterceptor[];
68
+ /** 响应拦截器 */
69
+ onResponse?: ResponseInterceptor[];
70
+ /** 错误拦截器 */
71
+ onError?: ErrorInterceptor[];
401
72
  }
402
73
  /**
403
- * 请求额外配置(每个请求可覆盖)
404
- */
405
- interface RequestOptions {
406
- /** 取消信号 */
407
- signal?: AbortSignal;
408
- /** 超时时间(覆盖全局配置) */
409
- timeoutMs?: number;
410
- /** 是否跳过重试 */
411
- skipRetry?: boolean;
412
- /** 额外请求头 */
413
- headers?: Record<string, string>;
74
+ * 认证配置
75
+ */
76
+ interface AuthConfig {
77
+ /** 认证类型 */
78
+ type: 'bearer' | 'api-key' | 'basic' | 'custom';
79
+ /** Token 获取函数 */
80
+ getToken?: () => Promise<string | null> | string | null;
81
+ /** API Key */
82
+ apiKey?: string;
83
+ /** API Key 头部名称 */
84
+ apiKeyHeader?: string;
85
+ /** Basic Auth 用户名 */
86
+ username?: string;
87
+ /** Basic Auth 密码 */
88
+ password?: string;
89
+ /** 自定义认证函数 */
90
+ customAuth?: (headers: Record<string, string>) => Promise<void> | void;
414
91
  }
415
92
  /**
416
- * SDK 版本信息(自动注入)
93
+ * 重试配置
417
94
  */
418
- interface SdkInfo {
419
- /** 包名 */
420
- name: string;
421
- /** 版本号 */
422
- version: string;
423
- /** 平台信息 */
424
- platform?: string;
95
+ interface RetryConfig {
96
+ /** 最大重试次数 */
97
+ maxRetries: number;
98
+ /** 初始延迟(毫秒) */
99
+ initialDelay: number;
100
+ /** 最大延迟(毫秒) */
101
+ maxDelay: number;
102
+ /** 退避策略 */
103
+ backoff: 'fixed' | 'exponential' | 'linear';
104
+ /** 可重试的 HTTP 状态码 */
105
+ retryableStatusCodes?: number[];
106
+ /** 是否重试网络错误 */
107
+ retryOnNetworkError?: boolean;
425
108
  }
426
109
  /**
427
- * Configuration 参数(兼容生成代码)
110
+ * 请求选项
428
111
  */
429
- interface ConfigurationParameters {
430
- basePath?: string;
431
- fetchApi?: typeof fetch;
432
- middleware?: Middleware[];
433
- credentials?: RequestCredentials;
434
- headers?: (() => Promise<Record<string, string>> | Record<string, string>) | Record<string, string>;
112
+ interface RequestOptions {
113
+ /** HTTP 方法 */
114
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
115
+ /** 请求路径 */
116
+ path: string;
117
+ /** 查询参数 */
118
+ query?: Record<string, string | number | boolean | undefined>;
119
+ /** 请求体 */
120
+ body?: unknown;
121
+ /** 请求头 */
122
+ headers?: Record<string, string>;
123
+ /** 超时时间 */
124
+ timeout?: number;
125
+ /** 是否跳过认证 */
126
+ skipAuth?: boolean;
127
+ /** 请求上下文 */
128
+ context?: Partial<RequestContext>;
435
129
  }
436
-
437
- /**
438
- * @djvlc/openapi-client-core - 工具函数
439
- */
440
- /**
441
- * 移除 URL 末尾的斜杠
442
- */
443
- declare function stripTrailingSlash(url: string): string;
444
- /**
445
- * 标准化 Headers
446
- */
447
- declare function normalizeHeaders(initHeaders: HeadersInit | undefined): Headers;
448
- /**
449
- * 合并多个 Headers
450
- */
451
- declare function mergeHeaders(...headersList: (HeadersInit | undefined)[]): Headers;
452
130
  /**
453
- * 延迟指定时间
454
- */
455
- declare function delay(ms: number): Promise<void>;
456
- /**
457
- * 计算指数退避延迟
458
- */
459
- declare function calculateBackoffDelay(attempt: number, baseDelayMs: number, maxDelayMs: number, exponential?: boolean): number;
460
- /**
461
- * 获取当前运行平台
462
- */
463
- declare function getPlatform(): string;
464
- /**
465
- * 生成 SDK User-Agent 字符串
466
- */
467
- declare function buildUserAgent(sdkName: string, sdkVersion: string): string;
468
- /**
469
- * 判断是否为浏览器环境
131
+ * 请求拦截器
470
132
  */
471
- declare function isBrowser(): boolean;
133
+ type RequestInterceptor = (options: RequestOptions) => Promise<RequestOptions>;
472
134
  /**
473
- * 安全解析 JSON
135
+ * 响应拦截器
474
136
  */
475
- declare function safeParseJson<T = unknown>(response: Response): Promise<T | null>;
137
+ type ResponseInterceptor = <T>(response: ApiSuccessResponse<T>, options: RequestOptions) => Promise<ApiSuccessResponse<T>>;
476
138
  /**
477
- * 克隆响应(用于读取 body 后仍保留原响应)
139
+ * 错误拦截器
478
140
  */
479
- declare function cloneResponse(response: Response): Response;
141
+ type ErrorInterceptor = (error: ApiError, options: RequestOptions) => Promise<void>;
480
142
 
481
143
  /**
482
- * @djvlc/openapi-client-core - Fetch 增强
144
+ * Axios 实例创建
483
145
  *
484
- * 提供超时、重试、取消等能力的 fetch 封装。
146
+ * 用于注入到 openapi-generator 生成的客户端
485
147
  */
486
148
 
487
- /**
488
- * 创建带超时的 fetch
489
- */
490
- declare function createFetchWithTimeout(fetchImpl: typeof fetch, timeoutMs: number): typeof fetch;
491
- /**
492
- * 创建带重试的 fetch
493
- */
494
- declare function createFetchWithRetry(fetchImpl: typeof fetch, options?: RetryOptions, logger?: Logger): typeof fetch;
495
- /**
496
- * 创建增强版 fetch(组合超时 + 重试 + 日志)
497
- */
498
- declare function createEnhancedFetch(options: {
499
- fetchApi?: typeof fetch;
500
- timeoutMs?: number;
501
- retry?: RetryOptions;
502
- logger?: Logger;
503
- }): typeof fetch;
504
- /**
505
- * 执行请求并处理错误
506
- *
507
- * 统一处理响应,非 2xx 响应转换为 DjvApiError
508
- */
509
- declare function executeRequest(fetchFn: typeof fetch, url: string, init: RequestInit, options?: RequestOptions): Promise<Response>;
149
+ declare module 'axios' {
150
+ interface InternalAxiosRequestConfig {
151
+ __retryCount?: number;
152
+ }
153
+ }
510
154
 
511
155
  /**
512
- * @djvlc/openapi-client-core - Middleware 系统
156
+ * 创建配置好的 Axios 实例
513
157
  *
514
- * 提供请求/响应拦截、认证注入、追踪头注入等能力。
515
- */
516
-
517
- /**
518
- * 创建 Headers 注入 Middleware
158
+ * 用于注入到 openapi-generator 生成的 API 类中
519
159
  *
520
- * 统一处理:
521
- * - 默认 Headers
522
- * - Bearer Token
523
- * - API Key
524
- * - Trace Headers
525
- * - SDK 版本
526
- */
527
- declare function createHeadersMiddleware(opts: {
528
- getAuthToken?: () => string | Promise<string>;
529
- getApiKey?: () => string | Promise<string>;
530
- getTraceHeaders?: () => Record<string, string>;
531
- defaultHeaders?: Record<string, string>;
532
- sdkInfo?: SdkInfo;
533
- }): Middleware;
534
- /**
535
- * 创建日志 Middleware
536
- */
537
- declare function createLoggingMiddleware(opts: {
538
- onRequest?: (url: string, init: RequestInit) => void;
539
- onResponse?: (url: string, response: Response, durationMs: number) => void;
540
- onError?: (url: string, error: unknown) => void;
541
- }): Middleware;
542
- /**
543
- * 应用 Middleware 链
544
- */
545
- declare function applyMiddlewareChain(middlewares: Middleware[], context: RequestContext): Promise<RequestContext>;
546
- /**
547
- * 应用 post Middleware 链
548
- */
549
- declare function applyPostMiddlewareChain(middlewares: Middleware[], context: ResponseContext): Promise<void>;
550
- /**
551
- * 从 ClientOptions 创建默认 Middleware 列表
160
+ * @example
161
+ * ```typescript
162
+ * import { createAxiosInstance } from '@djvlc/openapi-client-core';
163
+ * import { PagesApi, Configuration } from './generated';
164
+ *
165
+ * const axiosInstance = createAxiosInstance({
166
+ * baseUrl: '/api/admin',
167
+ * auth: { type: 'bearer', getToken: () => localStorage.getItem('token') },
168
+ * retry: { maxRetries: 2, initialDelay: 1000, maxDelay: 10000, backoff: 'exponential' },
169
+ * });
170
+ *
171
+ * const config = new Configuration();
172
+ * const pagesApi = new PagesApi(config, undefined, axiosInstance);
173
+ * ```
552
174
  */
553
- declare function createDefaultMiddlewares(opts: Pick<BaseClientOptions, 'getAuthToken' | 'getApiKey' | 'getTraceHeaders' | 'defaultHeaders' | 'logger' | 'debug'>, sdkInfo?: SdkInfo): Middleware[];
175
+ declare function createAxiosInstance(config: ClientConfig): AxiosInstance;
554
176
 
555
177
  /**
556
- * @djvlc/openapi-client-core - 拦截器系统
178
+ * 原生 fetch HTTP 客户端
557
179
  *
558
- * 提供更灵活的请求/响应/错误拦截能力。
180
+ * 保留兼容性,供不使用 axios 的场景使用
559
181
  */
560
182
 
561
183
  /**
562
- * 拦截器管理器
184
+ * 基础 HTTP 客户端
563
185
  */
564
- declare class InterceptorManager {
565
- private requestInterceptors;
566
- private responseInterceptors;
567
- private errorInterceptors;
568
- constructor(interceptors?: Interceptors);
186
+ declare class HttpClient {
187
+ private readonly config;
188
+ constructor(config: ClientConfig);
569
189
  /**
570
- * 添加请求拦截器
571
- * @returns 移除拦截器的函数
190
+ * 发起请求
572
191
  */
573
- addRequestInterceptor(interceptor: RequestInterceptor): () => void;
192
+ request<T>(options: RequestOptions): Promise<T>;
574
193
  /**
575
- * 添加响应拦截器
576
- * @returns 移除拦截器的函数
194
+ * GET 请求
577
195
  */
578
- addResponseInterceptor(interceptor: ResponseInterceptor): () => void;
196
+ get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
579
197
  /**
580
- * 添加错误拦截器
581
- * @returns 移除拦截器的函数
198
+ * POST 请求
582
199
  */
583
- addErrorInterceptor(interceptor: ErrorInterceptor): () => void;
200
+ post<T>(path: string, body?: unknown, query?: Record<string, string | number | boolean | undefined>): Promise<T>;
584
201
  /**
585
- * 执行请求拦截器链
202
+ * PUT 请求
586
203
  */
587
- runRequestInterceptors(context: RequestContext): Promise<RequestContext>;
588
- /**
589
- * 执行响应拦截器链
590
- */
591
- runResponseInterceptors(response: Response, context: RequestContext): Promise<Response>;
592
- /**
593
- * 执行错误拦截器链
594
- */
595
- runErrorInterceptors(error: unknown, context: RequestContext): Promise<unknown>;
596
- /**
597
- * 清除所有拦截器
598
- */
599
- clear(): void;
600
- }
601
- /**
602
- * 创建 Token 刷新拦截器
603
- *
604
- * 当收到 401 错误时自动刷新 token 并重试请求
605
- */
606
- declare function createTokenRefreshInterceptor(options: {
607
- /** 刷新 token 的函数 */
608
- refreshToken: () => Promise<string>;
609
- /** 判断是否需要刷新 */
610
- shouldRefresh?: (response: Response) => boolean;
611
- /** 最大刷新重试次数 */
612
- maxRetries?: number;
613
- }): ResponseInterceptor;
614
- /**
615
- * 创建请求去重拦截器
616
- *
617
- * 相同请求(URL + Method)在进行中时,复用同一个 Promise
618
- */
619
- declare function createDedupeInterceptor(): {
620
- interceptor: RequestInterceptor;
621
- clear: () => void;
622
- };
623
- /**
624
- * 创建请求缓存拦截器
625
- *
626
- * 缓存 GET 请求的响应
627
- */
628
- declare function createCacheInterceptor(options: {
629
- /** 缓存 TTL(毫秒) */
630
- ttlMs?: number;
631
- /** 判断是否应该缓存 */
632
- shouldCache?: (context: RequestContext) => boolean;
633
- /** 最大缓存条目数 */
634
- maxSize?: number;
635
- }): {
636
- requestInterceptor: RequestInterceptor;
637
- responseInterceptor: ResponseInterceptor;
638
- clear: () => void;
639
- };
640
-
641
- /**
642
- * @djvlc/openapi-client-core - 请求去重
643
- *
644
- * 避免相同的 GET 请求并发执行多次,复用进行中的请求。
645
- */
646
- /**
647
- * 请求去重器选项
648
- */
649
- interface DedupeOptions {
204
+ put<T>(path: string, body?: unknown): Promise<T>;
650
205
  /**
651
- * 生成请求唯一标识的函数
652
- *
653
- * 默认使用 `${method}:${url}`
206
+ * PATCH 请求
654
207
  */
655
- keyGenerator?: (url: string, init?: RequestInit) => string;
208
+ patch<T>(path: string, body?: unknown): Promise<T>;
656
209
  /**
657
- * 是否只对 GET 请求去重
658
- *
659
- * @default true
210
+ * DELETE 请求
660
211
  */
661
- getOnly?: boolean;
212
+ delete<T>(path: string): Promise<T>;
662
213
  /**
663
- * 调试日志
214
+ * 构建完整 URL
664
215
  */
665
- onDedupe?: (key: string, pending: number) => void;
666
- }
667
- /**
668
- * 请求去重器
669
- *
670
- * @example
671
- * ```typescript
672
- * const deduper = createRequestDeduper();
673
- *
674
- * // 包装 fetch
675
- * const dedupedFetch = deduper.wrap(fetch);
676
- *
677
- * // 相同的请求只会执行一次
678
- * const [r1, r2] = await Promise.all([
679
- * dedupedFetch('/api/user'),
680
- * dedupedFetch('/api/user'),
681
- * ]);
682
- * ```
683
- */
684
- declare function createRequestDeduper(options?: DedupeOptions): {
216
+ private buildUrl;
685
217
  /**
686
- * 包装 fetch 函数,添加请求去重能力
218
+ * 构建请求头
687
219
  */
688
- wrap: (fetchFn: typeof fetch) => typeof fetch;
220
+ private buildHeaders;
689
221
  /**
690
- * 获取当前进行中的请求数量
222
+ * 带重试的请求执行
691
223
  */
692
- getPendingCount(): number;
224
+ private executeWithRetry;
693
225
  /**
694
- * 获取所有进行中的请求 key
226
+ * 执行单次请求
695
227
  */
696
- getPendingKeys(): string[];
228
+ private execute;
697
229
  /**
698
- * 清除所有进行中的请求记录
699
- *
700
- * 注意:这不会取消请求,只是清除去重映射
230
+ * 判断是否应该重试
701
231
  */
702
- clear(): void;
703
- };
704
- /**
705
- * 请求去重器类型
706
- */
707
- type RequestDeduper = ReturnType<typeof createRequestDeduper>;
708
-
709
- /**
710
- * @djvlc/openapi-client-core - 指标收集
711
- *
712
- * 提供请求级别的指标收集能力,用于可观测性和性能监控。
713
- */
714
-
715
- /**
716
- * 请求指标
717
- */
718
- interface RequestMetrics {
719
- /** 请求 ID(唯一标识) */
720
- requestId: string;
721
- /** 请求 URL */
722
- url: string;
723
- /** 请求路径(不含 base URL 和 query) */
724
- path: string;
725
- /** HTTP 方法 */
726
- method: string;
727
- /** 请求开始时间戳(毫秒) */
728
- startTime: number;
729
- /** 请求结束时间戳(毫秒) */
730
- endTime: number;
731
- /** 请求耗时(毫秒) */
732
- durationMs: number;
733
- /** HTTP 状态码 */
734
- status: number;
735
- /** 是否成功(2xx) */
736
- success: boolean;
737
- /** 是否来自缓存 */
738
- fromCache?: boolean;
739
- /** 重试次数 */
740
- retryCount?: number;
741
- /** 请求体大小(字节) */
742
- requestSize?: number;
743
- /** 响应体大小(字节,如果可获取) */
744
- responseSize?: number;
745
- /** 错误信息(如果失败) */
746
- error?: string;
747
- /** 追踪 ID */
748
- traceId?: string;
749
- }
750
- /**
751
- * 指标摘要
752
- */
753
- interface MetricsSummary {
754
- /** 总请求数 */
755
- totalRequests: number;
756
- /** 成功请求数 */
757
- successCount: number;
758
- /** 失败请求数 */
759
- failureCount: number;
760
- /** 成功率 */
761
- successRate: number;
762
- /** 平均耗时(毫秒) */
763
- avgDurationMs: number;
764
- /** P50 耗时(毫秒) */
765
- p50Ms: number;
766
- /** P90 耗时(毫秒) */
767
- p90Ms: number;
768
- /** P95 耗时(毫秒) */
769
- p95Ms: number;
770
- /** P99 耗时(毫秒) */
771
- p99Ms: number;
772
- /** 最小耗时(毫秒) */
773
- minMs: number;
774
- /** 最大耗时(毫秒) */
775
- maxMs: number;
776
- /** 按状态码分组的计数 */
777
- statusCodeCounts: Record<number, number>;
778
- /** 按路径分组的计数 */
779
- pathCounts: Record<string, number>;
780
- /** 统计时间范围 */
781
- timeRange: {
782
- start: number;
783
- end: number;
784
- };
785
- }
786
- /**
787
- * 指标收集器选项
788
- */
789
- interface MetricsCollectorOptions {
790
- /** 最大保留的指标数量(避免内存泄漏) */
791
- maxMetrics?: number;
792
- /** 指标 TTL(毫秒,超过此时间的指标会被清理) */
793
- ttlMs?: number;
794
- /** 是否自动清理过期指标 */
795
- autoCleanup?: boolean;
796
- /** 清理间隔(毫秒) */
797
- cleanupIntervalMs?: number;
798
- /** 指标收集回调(每次请求完成时调用) */
799
- onMetrics?: (metrics: RequestMetrics) => void;
800
- }
801
- /**
802
- * 指标收集器
803
- */
804
- interface MetricsCollector {
805
- /** 收集指标 */
806
- collect(metrics: RequestMetrics): void;
807
- /** 获取所有指标 */
808
- getMetrics(): RequestMetrics[];
809
- /** 获取并清空所有指标 */
810
- flush(): RequestMetrics[];
811
- /** 获取指标摘要 */
812
- summary(): MetricsSummary;
813
- /** 按路径获取指标 */
814
- getByPath(path: string): RequestMetrics[];
815
- /** 按时间范围获取指标 */
816
- getByTimeRange(startTime: number, endTime: number): RequestMetrics[];
817
- /** 清除所有指标 */
818
- clear(): void;
819
- /** 销毁收集器(清理定时器等) */
820
- destroy(): void;
232
+ private shouldRetry;
821
233
  }
822
234
  /**
823
- * 创建指标收集器
824
- *
825
- * @example
826
- * ```typescript
827
- * const metrics = createMetricsCollector({
828
- * maxMetrics: 1000,
829
- * onMetrics: (m) => console.log(`${m.method} ${m.path} - ${m.durationMs}ms`),
830
- * });
831
- *
832
- * // 使用 middleware 收集指标
833
- * const client = createClient({
834
- * middleware: [createMetricsMiddleware(metrics)],
835
- * });
836
- *
837
- * // 获取摘要
838
- * const summary = metrics.summary();
839
- * console.log(`成功率: ${(summary.successRate * 100).toFixed(1)}%`);
840
- * console.log(`P95: ${summary.p95Ms}ms`);
841
- * ```
842
- */
843
- declare function createMetricsCollector(options?: MetricsCollectorOptions): MetricsCollector;
844
- /**
845
- * 创建指标收集 Middleware
846
- *
847
- * @example
848
- * ```typescript
849
- * const metrics = createMetricsCollector();
850
- * const middleware = createMetricsMiddleware(metrics);
851
- *
852
- * const client = createClient({
853
- * middleware: [middleware],
854
- * });
855
- * ```
235
+ * 创建 HTTP 客户端
856
236
  */
857
- declare function createMetricsMiddleware(collector: MetricsCollector): Middleware;
237
+ declare function createClient(config: ClientConfig): HttpClient;
858
238
 
859
239
  /**
860
- * @djvlc/openapi-client-core - 日志系统
240
+ * 工具函数
861
241
  */
862
242
 
863
243
  /**
864
- * 创建控制台日志器
244
+ * 生成请求 ID
865
245
  */
866
- declare function createConsoleLogger(options?: {
867
- /** 日志前缀 */
868
- prefix?: string;
869
- /** 是否启用 */
870
- enabled?: boolean;
871
- /** 日志级别:'debug' | 'info' | 'warn' | 'error' */
872
- level?: 'debug' | 'info' | 'warn' | 'error';
873
- /** 是否包含时间戳 */
874
- timestamp?: boolean;
875
- /** 是否包含请求体 */
876
- includeBody?: boolean;
877
- }): Logger;
246
+ declare function generateRequestId(): string;
878
247
  /**
879
- * 创建静默日志器(不输出任何日志)
248
+ * 延迟执行
880
249
  */
881
- declare function createSilentLogger(): Logger;
250
+ declare function sleep(ms: number): Promise<void>;
882
251
  /**
883
- * 创建自定义日志器
884
- *
885
- * 将日志发送到自定义目标(如监控系统)
252
+ * 计算重试延迟
886
253
  */
887
- declare function createCustomLogger(handlers: {
888
- onRequest?: (data: {
889
- url: string;
890
- method: string;
891
- headers?: Record<string, string>;
892
- timestamp: number;
893
- }) => void;
894
- onResponse?: (data: {
895
- url: string;
896
- status: number;
897
- durationMs: number;
898
- timestamp: number;
899
- }) => void;
900
- onError?: (data: {
901
- url: string;
902
- error: unknown;
903
- timestamp: number;
904
- }) => void;
905
- onRetry?: (data: {
906
- url: string;
907
- attempt: number;
908
- error: unknown;
909
- timestamp: number;
910
- }) => void;
911
- }): Logger;
912
- /**
913
- * 组合多个日志器
914
- */
915
- declare function combineLoggers(...loggers: Logger[]): Logger;
254
+ declare function calculateRetryDelay(retry: RetryConfig, attempt: number): number;
916
255
 
917
256
  /**
918
- * @djvlc/openapi-client-core - Configuration 类
257
+ * @djvlc/openapi-client-core
919
258
  *
920
- * 兼容 openapi-generator 生成的代码,同时提供增强能力。
921
- */
922
-
923
- /**
924
- * API 配置类
925
- *
926
- * 兼容 openapi-generator 的 Configuration,同时提供增强能力。
927
- */
928
- declare class Configuration {
929
- /** 基础路径 */
930
- basePath: string;
931
- /** fetch 实现 */
932
- fetchApi: typeof fetch;
933
- /** Middleware 列表 */
934
- middleware: Middleware[];
935
- /** Cookie 策略 */
936
- credentials?: RequestCredentials;
937
- /** 拦截器管理器 */
938
- interceptors: InterceptorManager;
939
- /** SDK 信息 */
940
- sdkInfo?: SdkInfo;
941
- constructor(params?: ConfigurationParameters);
942
- /**
943
- * 从 ClientOptions 创建 Configuration
944
- */
945
- static fromClientOptions(opts: BaseClientOptions, sdkInfo?: SdkInfo): Configuration;
946
- }
947
- /**
948
- * 创建兼容 openapi-generator 的 Configuration
259
+ * OpenAPI 客户端公共运行时
949
260
  *
950
- * 这个函数用于快速创建一个简单的配置,兼容生成的 API 类。
951
- */
952
- declare function createConfiguration(opts: BaseClientOptions, sdkInfo?: SdkInfo): Configuration;
953
-
954
- /**
955
- * @djvlc/openapi-client-core - 客户端工厂
261
+ * 提供:
262
+ * - Axios 实例创建(用于注入 openapi-generator 生成的客户端)
263
+ * - 原生 fetch HTTP 客户端
264
+ * - 认证处理(bearer/api-key/basic/custom)
265
+ * - 错误处理
266
+ * - 重试机制
267
+ * - 请求/响应拦截器
956
268
  *
957
- * 提供通用的客户端创建逻辑。
269
+ * @packageDocumentation
958
270
  */
959
271
 
960
- /**
961
- * API 类构造函数类型
962
- */
963
- type ApiConstructor<T> = new (configuration: Configuration) => T;
964
- /**
965
- * API 类映射
966
- */
967
- type ApiMap = Record<string, ApiConstructor<unknown>>;
968
- /**
969
- * 从 API 类映射提取实例类型
970
- */
971
- type ApiInstances<T extends ApiMap> = {
972
- [K in keyof T]: InstanceType<T[K]>;
973
- };
974
- /**
975
- * 创建客户端的通用工厂函数
976
- *
977
- * @example
978
- * ```typescript
979
- * import * as apis from './gen/apis';
980
- *
981
- * const client = createClient(apis, {
982
- * baseUrl: 'https://api.example.com',
983
- * getAuthToken: () => token,
984
- * }, { name: '@djvlc/openapi-user-client', version: '1.0.0' });
985
- * ```
986
- */
987
- declare function createClient<T extends ApiMap>(apiClasses: T, opts: BaseClientOptions, sdkInfo?: SdkInfo): {
988
- config: Configuration;
989
- apis: ApiInstances<T>;
990
- } & ApiInstances<T>;
991
- /**
992
- * 过滤出 API 类(以 'Api' 结尾的构造函数)
993
- */
994
- declare function filterApiClasses<T extends Record<string, unknown>>(exports: T): Record<string, ApiConstructor<unknown>>;
272
+ declare const VERSION = "2.0.0";
995
273
 
996
- export { AbortError, type ApiConstructor, type ApiInstances, type ApiMap, type BaseClientOptions, Configuration, type ConfigurationParameters, type DedupeOptions, DjvApiError, type ErrorInterceptor, InterceptorManager, type Interceptors, type Logger, type MetricsCollector, type MetricsCollectorOptions, type MetricsSummary, type Middleware, NetworkError, type RequestContext, type RequestDeduper, type RequestInterceptor, type RequestMetrics, type RequestOptions, type ResponseContext, type ResponseInterceptor, type RetryOptions, SDK_NAME, SDK_VERSION, type SdkInfo, TimeoutError, applyMiddlewareChain, applyPostMiddlewareChain, buildUserAgent, calculateBackoffDelay, cloneResponse, combineLoggers, createCacheInterceptor, createClient, createConfiguration, createConsoleLogger, createCustomLogger, createDedupeInterceptor, createDefaultMiddlewares, createEnhancedFetch, createFetchWithRetry, createFetchWithTimeout, createHeadersMiddleware, createLoggingMiddleware, createMetricsCollector, createMetricsMiddleware, createRequestDeduper, createSilentLogger, createTokenRefreshInterceptor, delay, executeRequest, filterApiClasses, getPlatform, getRetryDelay, getSdkInfo, isBrowser, isRetryableError, mergeHeaders, normalizeHeaders, safeParseJson, stripTrailingSlash };
274
+ export { ApiError, type AuthConfig, type ClientConfig, type ErrorInterceptor, HttpClient, NetworkError, type RequestInterceptor, type RequestOptions, type ResponseInterceptor, type RetryConfig, TimeoutError, VERSION, calculateRetryDelay, createAxiosInstance, createClient, generateRequestId, sleep };