@ahoo-wang/fetcher 0.3.6 → 0.5.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.
Files changed (3) hide show
  1. package/README.md +91 -188
  2. package/README.zh-CN.md +87 -183
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -6,83 +6,63 @@
6
6
  [![License](https://img.shields.io/npm/l/@ahoo-wang/fetcher.svg)](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
7
7
  [![npm downloads](https://img.shields.io/npm/dm/@ahoo-wang/fetcher.svg)](https://www.npmjs.com/package/@ahoo-wang/fetcher)
8
8
 
9
- A modern HTTP client library based on the Fetch API, designed to simplify and optimize interactions with backend RESTful APIs. It provides an Axios-like API with support for path parameters, query parameters, timeout settings, and request/response interceptors.
9
+ A modern, lightweight HTTP client library based on the Fetch API, designed to simplify and optimize interactions with
10
+ backend RESTful APIs. It provides an Axios-like API with support for path parameters, query parameters, timeout
11
+ settings, and request/response interceptors.
10
12
 
11
- ## Features
13
+ ## 🌟 Features
12
14
 
13
- - **Fetch API Compatible**: Fetcher's API is fully compatible with the native Fetch API, making it easy to get started.
14
- - **Path and Query Parameters**: Supports path parameters and query parameters in requests, with path parameters wrapped in `{}`.
15
- - **Timeout Settings**: Request timeout can be configured.
16
- - **Request Interceptors**: Supports modifying requests before they are sent.
17
- - **Response Interceptors**: Supports processing responses after they are returned.
18
- - **Error Interceptors**: Supports handling errors during the request lifecycle.
19
- - **Modular Design**: Clear code structure for easy maintenance and extension.
20
- - **Automatic Request Body Conversion**: Automatically converts plain objects to JSON and sets appropriate Content-Type headers.
21
- - **TypeScript Support**: Complete TypeScript type definitions.
15
+ - **🔄 Fetch API Compatible**: Fully compatible with the native Fetch API for easy adoption
16
+ - **🧭 Path & Query Parameters**: Native support for path parameters (`{id}`) and query parameters
17
+ - **⏱️ Timeout Control**: Configurable request timeouts with proper error handling
18
+ - **🔗 Interceptor System**: Request, response, and error interceptors for middleware patterns
19
+ - **🎯 Automatic Body Conversion**: Converts JavaScript objects to JSON with proper headers
20
+ - **🛡️ TypeScript Support**: Complete TypeScript definitions for type-safe development
21
+ - **🧩 Modular Architecture**: Lightweight core with optional extension packages
22
+ - **📦 Named Fetcher Support**: Automatic registration and retrieval of fetcher instances
23
+ - **⚙️ Default Fetcher**: Pre-configured default fetcher instance for quick start
22
24
 
23
- ## Installation
25
+ ## 🚀 Quick Start
24
26
 
25
- Using pnpm:
26
-
27
- ```bash
28
- pnpm add @ahoo-wang/fetcher
29
- ```
30
-
31
- Using npm:
27
+ ### Installation
32
28
 
33
29
  ```bash
30
+ # Using npm
34
31
  npm install @ahoo-wang/fetcher
35
- ```
36
32
 
37
- Using yarn:
33
+ # Using pnpm
34
+ pnpm add @ahoo-wang/fetcher
38
35
 
39
- ```bash
36
+ # Using yarn
40
37
  yarn add @ahoo-wang/fetcher
41
38
  ```
42
39
 
43
- ## Usage
44
-
45
40
  ### Basic Usage
46
41
 
47
42
  ```typescript
48
43
  import { Fetcher } from '@ahoo-wang/fetcher';
49
44
 
45
+ // Create a fetcher instance
50
46
  const fetcher = new Fetcher({
51
47
  baseURL: 'https://api.example.com',
52
48
  timeout: 5000,
53
49
  });
54
50
 
55
- // GET request with path parameters and query parameters
56
- fetcher
57
- .get('/users/{id}', {
58
- pathParams: { id: 123 },
59
- queryParams: { include: 'profile' },
60
- })
61
- .then(response => {
62
- console.log(response.data);
63
- })
64
- .catch(error => {
65
- console.error(error);
66
- });
51
+ // GET request with path and query parameters
52
+ const response = await fetcher.get('/users/{id}', {
53
+ pathParams: { id: 123 },
54
+ queryParams: { include: 'profile' },
55
+ });
56
+ const userData = await response.json();
67
57
 
68
- // POST request with JSON body (automatically converted to JSON string)
69
- fetcher
70
- .post('/users', {
71
- body: { name: 'John Doe', email: 'john@example.com' },
72
- })
73
- .then(response => {
74
- console.log(response.data);
75
- })
76
- .catch(error => {
77
- console.error(error);
78
- });
58
+ // POST request with automatic JSON conversion
59
+ const createUserResponse = await fetcher.post('/users', {
60
+ body: { name: 'John Doe', email: 'john@example.com' },
61
+ });
79
62
  ```
80
63
 
81
64
  ### Named Fetcher Usage
82
65
 
83
- NamedFetcher is an extension of the Fetcher class that automatically registers itself with a global registrar. This is
84
- useful when you need to manage multiple fetcher instances throughout your application.
85
-
86
66
  ```typescript
87
67
  import { NamedFetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';
88
68
 
@@ -96,30 +76,16 @@ const apiFetcher = new NamedFetcher('api', {
96
76
  },
97
77
  });
98
78
 
99
- // Create another named fetcher for a different service
100
- const authFetcher = new NamedFetcher('auth', {
101
- baseURL: 'https://auth.example.com',
102
- timeout: 3000,
103
- });
104
-
105
- // Use the fetcher normally
106
- apiFetcher
107
- .get('/users/123')
108
- .then(response => response.json())
109
- .then(data => console.log(data));
110
-
111
79
  // Retrieve a named fetcher from the registrar
112
80
  const retrievedFetcher = fetcherRegistrar.get('api');
113
81
  if (retrievedFetcher) {
114
- retrievedFetcher.post('/users', {
115
- body: { name: 'Jane Doe' },
116
- });
82
+ const response = await retrievedFetcher.get('/users/123');
117
83
  }
118
84
 
119
85
  // Use requiredGet to retrieve a fetcher (throws error if not found)
120
86
  try {
121
87
  const authFetcher = fetcherRegistrar.requiredGet('auth');
122
- authFetcher.post('/login', {
88
+ await authFetcher.post('/login', {
123
89
  body: { username: 'user', password: 'pass' },
124
90
  });
125
91
  } catch (error) {
@@ -129,68 +95,72 @@ try {
129
95
 
130
96
  ### Default Fetcher Usage
131
97
 
132
- The library also exports a pre-configured default fetcher instance that can be used directly:
133
-
134
98
  ```typescript
135
99
  import { fetcher } from '@ahoo-wang/fetcher';
136
100
 
137
101
  // Use the default fetcher directly
138
- fetcher
139
- .get('/users')
140
- .then(response => response.json())
141
- .then(data => console.log(data));
142
-
143
- // The default fetcher is also available through the registrar
144
- import { fetcherRegistrar } from '@ahoo-wang/fetcher';
145
-
146
- const defaultFetcher = fetcherRegistrar.default;
147
- // defaultFetcher is the same instance as fetcher
148
- console.log(defaultFetcher === fetcher); // true
102
+ const response = await fetcher.get('/users');
103
+ const data = await response.json();
149
104
  ```
150
105
 
151
- ### Interceptor Usage
106
+ ## 🔗 Interceptor System
107
+
108
+ ### Request Interceptors
152
109
 
153
110
  ```typescript
154
111
  import { Fetcher } from '@ahoo-wang/fetcher';
155
112
 
156
113
  const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
157
114
 
158
- // Add request interceptor
159
- const requestInterceptorId = fetcher.interceptors.request.use({
115
+ // Add request interceptor (e.g., for authentication)
116
+ const interceptorId = fetcher.interceptors.request.use({
160
117
  intercept(exchange) {
161
- // Modify request configuration, e.g., add auth header
162
118
  return {
163
119
  ...exchange,
164
120
  request: {
165
121
  ...exchange.request,
166
122
  headers: {
167
123
  ...exchange.request.headers,
168
- Authorization: 'Bearer token',
124
+ Authorization: 'Bearer ' + getAuthToken(),
169
125
  },
170
126
  },
171
127
  };
172
128
  },
173
129
  });
174
130
 
175
- // Add response interceptor
176
- const responseInterceptorId = fetcher.interceptors.response.use({
131
+ // Remove interceptor
132
+ fetcher.interceptors.request.eject(interceptorId);
133
+ ```
134
+
135
+ ### Response Interceptors
136
+
137
+ ```typescript
138
+ // Add response interceptor (e.g., for logging)
139
+ fetcher.interceptors.response.use({
177
140
  intercept(exchange) {
178
- // Process response data, e.g., parse JSON
141
+ console.log('Response received:', exchange.response.status);
179
142
  return exchange;
180
143
  },
181
144
  });
145
+ ```
146
+
147
+ ### Error Interceptors
182
148
 
183
- // Add error interceptor
184
- const errorInterceptorId = fetcher.interceptors.error.use({
149
+ ```typescript
150
+ // Add error interceptor (e.g., for unified error handling)
151
+ fetcher.interceptors.error.use({
185
152
  intercept(exchange) {
186
- // Handle errors, e.g., log them
187
- console.error('Request failed:', exchange.error);
153
+ if (exchange.error?.name === 'FetchTimeoutError') {
154
+ console.error('Request timeout:', exchange.error.message);
155
+ } else {
156
+ console.error('Network error:', exchange.error?.message);
157
+ }
188
158
  return exchange;
189
159
  },
190
160
  });
191
161
  ```
192
162
 
193
- ## API Reference
163
+ ## 📚 API Reference
194
164
 
195
165
  ### Fetcher Class
196
166
 
@@ -199,14 +169,14 @@ Core HTTP client class that provides various HTTP methods.
199
169
  #### Constructor
200
170
 
201
171
  ```typescript
202
- new Fetcher(options: FetcherOptions = defaultOptions)
172
+ new Fetcher(options ? : FetcherOptions);
203
173
  ```
204
174
 
205
- **Parameters:**
175
+ **Options:**
206
176
 
207
- - `options.baseURL`: Base URL
208
- - `options.timeout`: Request timeout in milliseconds
209
- - `options.headers`: Default request headers
177
+ - `baseURL`: Base URL for all requests
178
+ - `timeout`: Request timeout in milliseconds
179
+ - `headers`: Default request headers
210
180
 
211
181
  #### Methods
212
182
 
@@ -221,25 +191,18 @@ new Fetcher(options: FetcherOptions = defaultOptions)
221
191
 
222
192
  ### NamedFetcher Class
223
193
 
224
- An extension of the Fetcher class that automatically registers itself with the global fetcherRegistrar using a provided
225
- name.
194
+ An extension of the Fetcher class that automatically registers itself with the global fetcherRegistrar.
226
195
 
227
196
  #### Constructor
228
197
 
229
198
  ```typescript
230
199
  new NamedFetcher(name
231
200
  :
232
- string, options
233
- :
234
- FetcherOptions = defaultOptions
201
+ string, options ? : FetcherOptions
235
202
  )
203
+ ;
236
204
  ```
237
205
 
238
- **Parameters:**
239
-
240
- - `name`: The name to register this fetcher under
241
- - `options`: Same as Fetcher constructor options
242
-
243
206
  ### FetcherRegistrar
244
207
 
245
208
  Global instance for managing multiple Fetcher instances by name.
@@ -256,112 +219,52 @@ Global instance for managing multiple Fetcher instances by name.
256
219
  - `requiredGet(name: string): Fetcher` - Get a fetcher by name, throws if not found
257
220
  - `fetchers: Map<string, Fetcher>` - Get all registered fetchers
258
221
 
259
- ### UrlBuilder Class
260
-
261
- URL builder for constructing complete URLs with parameters.
222
+ ### Interceptor System
262
223
 
263
- #### Methods
264
-
265
- - `build(path: string, pathParams?: Record<string, any>, queryParams?: Record<string, any>): string` - Build complete URL
266
-
267
- ### InterceptorManager Class
224
+ #### InterceptorManager
268
225
 
269
226
  Interceptor manager for managing multiple interceptors of the same type.
270
227
 
271
- #### Methods
228
+ **Methods:**
272
229
 
273
230
  - `use(interceptor: Interceptor): number` - Add interceptor, returns interceptor ID
274
231
  - `eject(index: number): void` - Remove interceptor by ID
275
232
  - `clear(): void` - Clear all interceptors
276
233
  - `intercept(exchange: FetchExchange): Promise<FetchExchange>` - Execute all interceptors sequentially
277
234
 
278
- ### FetcherInterceptors Class
235
+ #### FetcherInterceptors
279
236
 
280
237
  Fetcher interceptor collection, including request, response, and error interceptor managers.
281
238
 
282
- #### Properties
239
+ **Properties:**
283
240
 
284
241
  - `request: InterceptorManager` - Request interceptor manager
285
242
  - `response: InterceptorManager` - Response interceptor manager
286
243
  - `error: InterceptorManager` - Error interceptor manager
287
244
 
288
- ## Complete Example
289
-
290
- ```typescript
291
- import { Fetcher } from '@ahoo-wang/fetcher';
292
-
293
- // Create fetcher instance
294
- const fetcher = new Fetcher({
295
- baseURL: 'https://api.example.com',
296
- timeout: 10000,
297
- headers: {
298
- 'Content-Type': 'application/json',
299
- },
300
- });
245
+ ## 🛠️ Development
301
246
 
302
- // Add request interceptor - Add auth header
303
- fetcher.interceptors.request.use({
304
- intercept(exchange) {
305
- return {
306
- ...exchange,
307
- request: {
308
- ...exchange.request,
309
- headers: {
310
- ...exchange.request.headers,
311
- Authorization: 'Bearer ' + getAuthToken(),
312
- },
313
- },
314
- };
315
- },
316
- });
317
-
318
- // Add response interceptor - Process response
319
- fetcher.interceptors.response.use({
320
- intercept(exchange) {
321
- // Note: Response processing would typically happen after the response is received
322
- return exchange;
323
- },
324
- });
325
-
326
- // Add error interceptor - Unified error handling
327
- fetcher.interceptors.error.use({
328
- intercept(exchange) {
329
- if (exchange.error?.name === 'FetchTimeoutError') {
330
- console.error('Request timeout:', exchange.error.message);
331
- } else {
332
- console.error('Network error:', exchange.error?.message);
333
- }
334
- return exchange;
335
- },
336
- });
337
-
338
- // Use fetcher to make requests
339
- fetcher
340
- .get('/users/{id}', {
341
- pathParams: { id: 123 },
342
- queryParams: { include: 'profile,posts' },
343
- })
344
- .then(response => response.json())
345
- .then(data => {
346
- console.log('User data:', data);
347
- })
348
- .catch(error => {
349
- console.error('Failed to fetch user:', error);
350
- });
351
- ```
352
-
353
- ## Testing
354
-
355
- Run tests:
247
+ ### Testing
356
248
 
357
249
  ```bash
250
+ # Run tests
358
251
  pnpm test
252
+
253
+ # Run tests with coverage
254
+ pnpm test --coverage
359
255
  ```
360
256
 
361
- ## Contributing
257
+ ## 🤝 Contributing
362
258
 
363
- Contributions of any kind are welcome! Please see the [contributing guide](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) for more details.
259
+ Contributions are welcome! Please see
260
+ the [contributing guide](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) for more details.
364
261
 
365
- ## License
262
+ ## 📄 License
366
263
 
367
264
  This project is licensed under the [Apache-2.0 License](https://opensource.org/licenses/Apache-2.0).
265
+
266
+ ---
267
+
268
+ <p align="center">
269
+ Part of the <a href="https://github.com/Ahoo-Wang/fetcher">Fetcher</a> ecosystem
270
+ </p>
package/README.zh-CN.md CHANGED
@@ -6,83 +6,62 @@
6
6
  [![License](https://img.shields.io/npm/l/@ahoo-wang/fetcher.svg)](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
7
7
  [![npm downloads](https://img.shields.io/npm/dm/@ahoo-wang/fetcher.svg)](https://www.npmjs.com/package/@ahoo-wang/fetcher)
8
8
 
9
- 一个基于 Fetch API 的现代 HTTP 客户端库,旨在简化和优化与后端 RESTful API 的交互。它提供了类似 Axios 的 API,支持路径参数、查询参数、超时设置和请求/响应拦截器。
9
+ 一个基于 Fetch API 的现代、轻量级 HTTP 客户端库,旨在简化和优化与后端 RESTful API 的交互。它提供了类似 Axios 的
10
+ API,支持路径参数、查询参数、超时设置和请求/响应拦截器。
10
11
 
11
- ## 特性
12
+ ## 🌟 特性
12
13
 
13
- - **Fetch API 兼容**:Fetcher 的 API 与原生 Fetch API 完全兼容,易于上手。
14
- - **路径和查询参数**:支持请求中的路径参数和查询参数,路径参数用 `{}` 包装。
15
- - **超时设置**:可以配置请求超时。
16
- - **请求拦截器**:支持在发送请求前修改请求。
17
- - **响应拦截器**:支持在返回响应后处理响应。
18
- - **错误拦截器**:支持在请求生命周期中处理错误。
19
- - **模块化设计**:代码结构清晰,易于维护和扩展。
20
- - **自动请求体转换**:自动将普通对象转换为 JSON 并设置适当的 Content-Type 头部。
21
- - **TypeScript 支持**:完整的 TypeScript 类型定义。
14
+ - **🔄 Fetch API 兼容**:与原生 Fetch API 完全兼容,易于上手
15
+ - **🧭 路径和查询参数**:原生支持路径参数(`{id}`)和查询参数
16
+ - **⏱️ 超时控制**:可配置的请求超时和适当的错误处理
17
+ - **🔗 拦截器系统**:请求、响应和错误拦截器的中间件模式
18
+ - **🎯 自动请求体转换**:自动将 JavaScript 对象转换为 JSON 并设置适当头部
19
+ - **🛡️ TypeScript 支持**:完整的 TypeScript 类型定义,提升开发体验
20
+ - **🧩 模块化架构**:轻量级核心和可选的扩展包
21
+ - **📦 命名 Fetcher 支持**:自动注册和检索 fetcher 实例
22
+ - **⚙️ 默认 Fetcher**:预配置的默认 fetcher 实例,快速开始
22
23
 
23
- ## 安装
24
+ ## 🚀 快速开始
24
25
 
25
- 使用 pnpm:
26
-
27
- ```bash
28
- pnpm add @ahoo-wang/fetcher
29
- ```
30
-
31
- 使用 npm:
26
+ ### 安装
32
27
 
33
28
  ```bash
29
+ # 使用 npm
34
30
  npm install @ahoo-wang/fetcher
35
- ```
36
31
 
37
- 使用 yarn:
32
+ # 使用 pnpm
33
+ pnpm add @ahoo-wang/fetcher
38
34
 
39
- ```bash
35
+ # 使用 yarn
40
36
  yarn add @ahoo-wang/fetcher
41
37
  ```
42
38
 
43
- ## 使用
44
-
45
39
  ### 基本用法
46
40
 
47
41
  ```typescript
48
42
  import { Fetcher } from '@ahoo-wang/fetcher';
49
43
 
44
+ // 创建 fetcher 实例
50
45
  const fetcher = new Fetcher({
51
46
  baseURL: 'https://api.example.com',
52
47
  timeout: 5000,
53
48
  });
54
49
 
55
- // 带路径参数和查询参数的 GET 请求
56
- fetcher
57
- .get('/users/{id}', {
58
- pathParams: { id: 123 },
59
- queryParams: { include: 'profile' },
60
- })
61
- .then(response => {
62
- console.log(response.data);
63
- })
64
- .catch(error => {
65
- console.error(error);
66
- });
50
+ // 带路径和查询参数的 GET 请求
51
+ const response = await fetcher.get('/users/{id}', {
52
+ pathParams: { id: 123 },
53
+ queryParams: { include: 'profile' },
54
+ });
55
+ const userData = await response.json();
67
56
 
68
- // JSON 体的 POST 请求(自动转换为 JSON 字符串)
69
- fetcher
70
- .post('/users', {
71
- body: { name: 'John Doe', email: 'john@example.com' },
72
- })
73
- .then(response => {
74
- console.log(response.data);
75
- })
76
- .catch(error => {
77
- console.error(error);
78
- });
57
+ // 带自动 JSON 转换的 POST 请求
58
+ const createUserResponse = await fetcher.post('/users', {
59
+ body: { name: 'John Doe', email: 'john@example.com' },
60
+ });
79
61
  ```
80
62
 
81
63
  ### 命名 Fetcher 用法
82
64
 
83
- NamedFetcher 是 Fetcher 类的扩展,它会自动使用提供的名称在全局注册器中注册自己。当您需要在应用程序中管理多个 fetcher
84
- 实例时,这很有用。
85
-
86
65
  ```typescript
87
66
  import { NamedFetcher, fetcherRegistrar } from '@ahoo-wang/fetcher';
88
67
 
@@ -96,30 +75,16 @@ const apiFetcher = new NamedFetcher('api', {
96
75
  },
97
76
  });
98
77
 
99
- // 为不同的服务创建另一个命名 fetcher
100
- const authFetcher = new NamedFetcher('auth', {
101
- baseURL: 'https://auth.example.com',
102
- timeout: 3000,
103
- });
104
-
105
- // 正常使用 fetcher
106
- apiFetcher
107
- .get('/users/123')
108
- .then(response => response.json())
109
- .then(data => console.log(data));
110
-
111
78
  // 从注册器中检索命名 fetcher
112
79
  const retrievedFetcher = fetcherRegistrar.get('api');
113
80
  if (retrievedFetcher) {
114
- retrievedFetcher.post('/users', {
115
- body: { name: 'Jane Doe' },
116
- });
81
+ const response = await retrievedFetcher.get('/users/123');
117
82
  }
118
83
 
119
84
  // 使用 requiredGet 检索 fetcher(如果未找到则抛出错误)
120
85
  try {
121
86
  const authFetcher = fetcherRegistrar.requiredGet('auth');
122
- authFetcher.post('/login', {
87
+ await authFetcher.post('/login', {
123
88
  body: { username: 'user', password: 'pass' },
124
89
  });
125
90
  } catch (error) {
@@ -129,68 +94,72 @@ try {
129
94
 
130
95
  ### 默认 Fetcher 用法
131
96
 
132
- 该库还导出了一个预配置的默认 fetcher 实例,可以直接使用:
133
-
134
97
  ```typescript
135
98
  import { fetcher } from '@ahoo-wang/fetcher';
136
99
 
137
100
  // 直接使用默认 fetcher
138
- fetcher
139
- .get('/users')
140
- .then(response => response.json())
141
- .then(data => console.log(data));
142
-
143
- // 默认 fetcher 也可以通过注册器获取
144
- import { fetcherRegistrar } from '@ahoo-wang/fetcher';
145
-
146
- const defaultFetcher = fetcherRegistrar.default;
147
- // defaultFetcher 与 fetcher 是同一个实例
148
- console.log(defaultFetcher === fetcher); // true
101
+ const response = await fetcher.get('/users');
102
+ const data = await response.json();
149
103
  ```
150
104
 
151
- ### 拦截器用法
105
+ ## 🔗 拦截器系统
106
+
107
+ ### 请求拦截器
152
108
 
153
109
  ```typescript
154
110
  import { Fetcher } from '@ahoo-wang/fetcher';
155
111
 
156
112
  const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
157
113
 
158
- // 添加请求拦截器
159
- const requestInterceptorId = fetcher.interceptors.request.use({
114
+ // 添加请求拦截器(例如用于认证)
115
+ const interceptorId = fetcher.interceptors.request.use({
160
116
  intercept(exchange) {
161
- // 修改请求配置,例如添加认证头部
162
117
  return {
163
118
  ...exchange,
164
119
  request: {
165
120
  ...exchange.request,
166
121
  headers: {
167
122
  ...exchange.request.headers,
168
- Authorization: 'Bearer token',
123
+ Authorization: 'Bearer ' + getAuthToken(),
169
124
  },
170
125
  },
171
126
  };
172
127
  },
173
128
  });
174
129
 
175
- // 添加响应拦截器
176
- const responseInterceptorId = fetcher.interceptors.response.use({
130
+ // 移除拦截器
131
+ fetcher.interceptors.request.eject(interceptorId);
132
+ ```
133
+
134
+ ### 响应拦截器
135
+
136
+ ```typescript
137
+ // 添加响应拦截器(例如用于日志记录)
138
+ fetcher.interceptors.response.use({
177
139
  intercept(exchange) {
178
- // 处理响应数据,例如解析 JSON
140
+ console.log('收到响应:', exchange.response.status);
179
141
  return exchange;
180
142
  },
181
143
  });
144
+ ```
182
145
 
183
- // 添加错误拦截器
184
- const errorInterceptorId = fetcher.interceptors.error.use({
146
+ ### 错误拦截器
147
+
148
+ ```typescript
149
+ // 添加错误拦截器(例如用于统一错误处理)
150
+ fetcher.interceptors.error.use({
185
151
  intercept(exchange) {
186
- // 处理错误,例如记录日志
187
- console.error('请求失败:', exchange.error);
152
+ if (exchange.error?.name === 'FetchTimeoutError') {
153
+ console.error('请求超时:', exchange.error.message);
154
+ } else {
155
+ console.error('网络错误:', exchange.error?.message);
156
+ }
188
157
  return exchange;
189
158
  },
190
159
  });
191
160
  ```
192
161
 
193
- ## API 参考
162
+ ## 📚 API 参考
194
163
 
195
164
  ### Fetcher 类
196
165
 
@@ -199,14 +168,14 @@ const errorInterceptorId = fetcher.interceptors.error.use({
199
168
  #### 构造函数
200
169
 
201
170
  ```typescript
202
- new Fetcher(options?: FetcherOptions)
171
+ new Fetcher(options ? : FetcherOptions);
203
172
  ```
204
173
 
205
- **参数:**
174
+ **选项:**
206
175
 
207
- - `options.baseURL`:基础 URL
208
- - `options.timeout`:以毫秒为单位的请求超时
209
- - `options.headers`:默认请求头部
176
+ - `baseURL`:基础 URL
177
+ - `timeout`:以毫秒为单位的请求超时
178
+ - `headers`:默认请求头部
210
179
 
211
180
  #### 方法
212
181
 
@@ -230,13 +199,9 @@ new NamedFetcher(name
230
199
  :
231
200
  string, options ? : FetcherOptions
232
201
  )
202
+ ;
233
203
  ```
234
204
 
235
- **参数:**
236
-
237
- - `name`:注册此 fetcher 的名称
238
- - `options`:与 Fetcher 构造函数相同的选项
239
-
240
205
  ### FetcherRegistrar
241
206
 
242
207
  用于按名称管理多个 Fetcher 实例的全局实例。
@@ -253,112 +218,51 @@ string, options ? : FetcherOptions
253
218
  - `requiredGet(name: string): Fetcher` - 按名称获取 fetcher,如果未找到则抛出错误
254
219
  - `fetchers: Map<string, Fetcher>` - 获取所有已注册的 fetcher
255
220
 
256
- ### UrlBuilder 类
257
-
258
- 用于构建带参数的完整 URL 的 URL 构建器。
259
-
260
- #### 方法
261
-
262
- - `build(path: string, pathParams?: Record<string, any>, queryParams?: Record<string, any>): string` - 构建完整 URL
221
+ ### 拦截器系统
263
222
 
264
- ### InterceptorManager
223
+ #### InterceptorManager
265
224
 
266
225
  用于管理同一类型多个拦截器的拦截器管理器。
267
226
 
268
- #### 方法
227
+ **方法:**
269
228
 
270
229
  - `use(interceptor: Interceptor): number` - 添加拦截器,返回拦截器 ID
271
230
  - `eject(index: number): void` - 按 ID 移除拦截器
272
231
  - `clear(): void` - 清除所有拦截器
273
232
  - `intercept(exchange: FetchExchange): Promise<FetchExchange>` - 顺序执行所有拦截器
274
233
 
275
- ### FetcherInterceptors
234
+ #### FetcherInterceptors
276
235
 
277
236
  Fetcher 拦截器集合,包括请求、响应和错误拦截器管理器。
278
237
 
279
- #### 属性
238
+ **属性:**
280
239
 
281
240
  - `request: InterceptorManager` - 请求拦截器管理器
282
241
  - `response: InterceptorManager` - 响应拦截器管理器
283
242
  - `error: InterceptorManager` - 错误拦截器管理器
284
243
 
285
- ## 完整示例
244
+ ## 🛠️ 开发
286
245
 
287
- ```typescript
288
- import { Fetcher } from '@ahoo-wang/fetcher';
289
-
290
- // 创建 fetcher 实例
291
- const fetcher = new Fetcher({
292
- baseURL: 'https://api.example.com',
293
- timeout: 10000,
294
- headers: {
295
- 'Content-Type': 'application/json',
296
- },
297
- });
298
-
299
- // 添加请求拦截器 - 添加认证头部
300
- fetcher.interceptors.request.use({
301
- intercept(exchange) {
302
- return {
303
- ...exchange,
304
- request: {
305
- ...exchange.request,
306
- headers: {
307
- ...exchange.request.headers,
308
- Authorization: 'Bearer ' + getAuthToken(),
309
- },
310
- },
311
- };
312
- },
313
- });
314
-
315
- // 添加响应拦截器 - 处理响应
316
- fetcher.interceptors.response.use({
317
- intercept(exchange) {
318
- // 注意:响应处理通常在收到响应后进行
319
- return exchange;
320
- },
321
- });
322
-
323
- // 添加错误拦截器 - 统一错误处理
324
- fetcher.interceptors.error.use({
325
- intercept(exchange) {
326
- if (exchange.error?.name === 'FetchTimeoutError') {
327
- console.error('请求超时:', exchange.error.message);
328
- } else {
329
- console.error('网络错误:', exchange.error?.message);
330
- }
331
- return exchange;
332
- },
333
- });
334
-
335
- // 使用 fetcher 发起请求
336
- fetcher
337
- .get('/users/{id}', {
338
- pathParams: { id: 123 },
339
- queryParams: { include: 'profile,posts' },
340
- })
341
- .then(response => response.json())
342
- .then(data => {
343
- console.log('用户数据:', data);
344
- })
345
- .catch(error => {
346
- console.error('获取用户失败:', error);
347
- });
348
- ```
349
-
350
- ## 测试
351
-
352
- 运行测试:
246
+ ### 测试
353
247
 
354
248
  ```bash
249
+ # 运行测试
355
250
  pnpm test
251
+
252
+ # 运行带覆盖率的测试
253
+ pnpm test --coverage
356
254
  ```
357
255
 
358
- ## 贡献
256
+ ## 🤝 贡献
359
257
 
360
- 欢迎任何形式的贡献!请查看 [贡献指南](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) 了解更多详情。
258
+ 欢迎贡献!请查看 [贡献指南](https://github.com/Ahoo-Wang/fetcher/blob/main/CONTRIBUTING.md) 了解更多详情。
361
259
 
362
- ## 许可证
260
+ ## 📄 许可证
363
261
 
364
262
  本项目采用 [Apache-2.0 许可证](https://opensource.org/licenses/Apache-2.0)。
263
+
264
+ ---
265
+
266
+ <p align="center">
267
+ Fetcher 生态系统的一部分
268
+ </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher",
3
- "version": "0.3.6",
3
+ "version": "0.5.0",
4
4
  "description": "Core library providing basic HTTP client functionality for Fetcher",
5
5
  "keywords": [
6
6
  "fetch",