@ahoo-wang/fetcher 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -34
- package/README.zh-CN.md +36 -34
- package/dist/fetcher.d.ts +64 -45
- package/dist/fetcher.d.ts.map +1 -1
- package/dist/index.es.js +163 -146
- package/dist/index.umd.js +1 -1
- package/dist/interceptor.d.ts +18 -40
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/requestBodyInterceptor.d.ts +4 -5
- package/dist/requestBodyInterceptor.d.ts.map +1 -1
- package/dist/timeout.d.ts +3 -4
- package/dist/timeout.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher)
|
|
4
4
|
[](https://github.com/Ahoo-Wang/fetcher/actions)
|
|
5
|
-
[](https://codecov.io/gh/Ahoo-Wang/fetcher)
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher)
|
|
8
8
|
|
|
@@ -87,13 +87,16 @@ const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
|
|
|
87
87
|
|
|
88
88
|
// Add request interceptor
|
|
89
89
|
const requestInterceptorId = fetcher.interceptors.request.use({
|
|
90
|
-
intercept(
|
|
90
|
+
intercept(exchange) {
|
|
91
91
|
// Modify request configuration, e.g., add auth header
|
|
92
92
|
return {
|
|
93
|
-
...
|
|
94
|
-
|
|
95
|
-
...request
|
|
96
|
-
|
|
93
|
+
...exchange,
|
|
94
|
+
request: {
|
|
95
|
+
...exchange.request,
|
|
96
|
+
headers: {
|
|
97
|
+
...exchange.request.headers,
|
|
98
|
+
Authorization: 'Bearer token',
|
|
99
|
+
},
|
|
97
100
|
},
|
|
98
101
|
};
|
|
99
102
|
},
|
|
@@ -101,18 +104,18 @@ const requestInterceptorId = fetcher.interceptors.request.use({
|
|
|
101
104
|
|
|
102
105
|
// Add response interceptor
|
|
103
106
|
const responseInterceptorId = fetcher.interceptors.response.use({
|
|
104
|
-
intercept(
|
|
107
|
+
intercept(exchange) {
|
|
105
108
|
// Process response data, e.g., parse JSON
|
|
106
|
-
return
|
|
109
|
+
return exchange;
|
|
107
110
|
},
|
|
108
111
|
});
|
|
109
112
|
|
|
110
113
|
// Add error interceptor
|
|
111
114
|
const errorInterceptorId = fetcher.interceptors.error.use({
|
|
112
|
-
intercept(
|
|
115
|
+
intercept(exchange) {
|
|
113
116
|
// Handle errors, e.g., log them
|
|
114
|
-
console.error('Request failed:', error);
|
|
115
|
-
return
|
|
117
|
+
console.error('Request failed:', exchange.error);
|
|
118
|
+
return exchange;
|
|
116
119
|
},
|
|
117
120
|
});
|
|
118
121
|
```
|
|
@@ -160,10 +163,10 @@ Interceptor manager for managing multiple interceptors of the same type.
|
|
|
160
163
|
|
|
161
164
|
#### Methods
|
|
162
165
|
|
|
163
|
-
- `use(interceptor:
|
|
166
|
+
- `use(interceptor: Interceptor): number` - Add interceptor, returns interceptor ID
|
|
164
167
|
- `eject(index: number): void` - Remove interceptor by ID
|
|
165
168
|
- `clear(): void` - Clear all interceptors
|
|
166
|
-
- `intercept(
|
|
169
|
+
- `intercept(exchange: FetchExchange): Promise<FetchExchange>` - Execute all interceptors sequentially
|
|
167
170
|
|
|
168
171
|
### FetcherInterceptors Class
|
|
169
172
|
|
|
@@ -171,9 +174,9 @@ Fetcher interceptor collection, including request, response, and error intercept
|
|
|
171
174
|
|
|
172
175
|
#### Properties
|
|
173
176
|
|
|
174
|
-
- `request:
|
|
175
|
-
- `response:
|
|
176
|
-
- `error:
|
|
177
|
+
- `request: InterceptorManager` - Request interceptor manager
|
|
178
|
+
- `response: InterceptorManager` - Response interceptor manager
|
|
179
|
+
- `error: InterceptorManager` - Error interceptor manager
|
|
177
180
|
|
|
178
181
|
## Complete Example
|
|
179
182
|
|
|
@@ -191,38 +194,37 @@ const fetcher = new Fetcher({
|
|
|
191
194
|
|
|
192
195
|
// Add request interceptor - Add auth header
|
|
193
196
|
fetcher.interceptors.request.use({
|
|
194
|
-
intercept(
|
|
197
|
+
intercept(exchange) {
|
|
195
198
|
return {
|
|
196
|
-
...
|
|
197
|
-
|
|
198
|
-
...request
|
|
199
|
-
|
|
199
|
+
...exchange,
|
|
200
|
+
request: {
|
|
201
|
+
...exchange.request,
|
|
202
|
+
headers: {
|
|
203
|
+
...exchange.request.headers,
|
|
204
|
+
Authorization: 'Bearer ' + getAuthToken(),
|
|
205
|
+
},
|
|
200
206
|
},
|
|
201
207
|
};
|
|
202
208
|
},
|
|
203
209
|
});
|
|
204
210
|
|
|
205
|
-
// Add response interceptor -
|
|
211
|
+
// Add response interceptor - Process response
|
|
206
212
|
fetcher.interceptors.response.use({
|
|
207
|
-
intercept(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return new Response(JSON.stringify(data), response);
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
return response;
|
|
213
|
+
intercept(exchange) {
|
|
214
|
+
// Note: Response processing would typically happen after the response is received
|
|
215
|
+
return exchange;
|
|
214
216
|
},
|
|
215
217
|
});
|
|
216
218
|
|
|
217
219
|
// Add error interceptor - Unified error handling
|
|
218
220
|
fetcher.interceptors.error.use({
|
|
219
|
-
intercept(
|
|
220
|
-
if (error
|
|
221
|
-
console.error('Request timeout:', error.message);
|
|
221
|
+
intercept(exchange) {
|
|
222
|
+
if (exchange.error?.name === 'FetchTimeoutError') {
|
|
223
|
+
console.error('Request timeout:', exchange.error.message);
|
|
222
224
|
} else {
|
|
223
|
-
console.error('Network error:', error
|
|
225
|
+
console.error('Network error:', exchange.error?.message);
|
|
224
226
|
}
|
|
225
|
-
return
|
|
227
|
+
return exchange;
|
|
226
228
|
},
|
|
227
229
|
});
|
|
228
230
|
|
package/README.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher)
|
|
4
4
|
[](https://github.com/Ahoo-Wang/fetcher/actions)
|
|
5
|
-
[](https://codecov.io/gh/Ahoo-Wang/fetcher)
|
|
6
6
|
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
7
|
[](https://www.npmjs.com/package/@ahoo-wang/fetcher)
|
|
8
8
|
|
|
@@ -87,13 +87,16 @@ const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
|
|
|
87
87
|
|
|
88
88
|
// 添加请求拦截器
|
|
89
89
|
const requestInterceptorId = fetcher.interceptors.request.use({
|
|
90
|
-
intercept(
|
|
90
|
+
intercept(exchange) {
|
|
91
91
|
// 修改请求配置,例如添加认证头部
|
|
92
92
|
return {
|
|
93
|
-
...
|
|
94
|
-
|
|
95
|
-
...request
|
|
96
|
-
|
|
93
|
+
...exchange,
|
|
94
|
+
request: {
|
|
95
|
+
...exchange.request,
|
|
96
|
+
headers: {
|
|
97
|
+
...exchange.request.headers,
|
|
98
|
+
Authorization: 'Bearer token',
|
|
99
|
+
},
|
|
97
100
|
},
|
|
98
101
|
};
|
|
99
102
|
},
|
|
@@ -101,18 +104,18 @@ const requestInterceptorId = fetcher.interceptors.request.use({
|
|
|
101
104
|
|
|
102
105
|
// 添加响应拦截器
|
|
103
106
|
const responseInterceptorId = fetcher.interceptors.response.use({
|
|
104
|
-
intercept(
|
|
107
|
+
intercept(exchange) {
|
|
105
108
|
// 处理响应数据,例如解析 JSON
|
|
106
|
-
return
|
|
109
|
+
return exchange;
|
|
107
110
|
},
|
|
108
111
|
});
|
|
109
112
|
|
|
110
113
|
// 添加错误拦截器
|
|
111
114
|
const errorInterceptorId = fetcher.interceptors.error.use({
|
|
112
|
-
intercept(
|
|
115
|
+
intercept(exchange) {
|
|
113
116
|
// 处理错误,例如记录日志
|
|
114
|
-
console.error('请求失败:', error);
|
|
115
|
-
return
|
|
117
|
+
console.error('请求失败:', exchange.error);
|
|
118
|
+
return exchange;
|
|
116
119
|
},
|
|
117
120
|
});
|
|
118
121
|
```
|
|
@@ -160,10 +163,10 @@ new Fetcher(options?: FetcherOptions)
|
|
|
160
163
|
|
|
161
164
|
#### 方法
|
|
162
165
|
|
|
163
|
-
- `use(interceptor:
|
|
166
|
+
- `use(interceptor: Interceptor): number` - 添加拦截器,返回拦截器 ID
|
|
164
167
|
- `eject(index: number): void` - 按 ID 移除拦截器
|
|
165
168
|
- `clear(): void` - 清除所有拦截器
|
|
166
|
-
- `intercept(
|
|
169
|
+
- `intercept(exchange: FetchExchange): Promise<FetchExchange>` - 顺序执行所有拦截器
|
|
167
170
|
|
|
168
171
|
### FetcherInterceptors 类
|
|
169
172
|
|
|
@@ -171,9 +174,9 @@ Fetcher 拦截器集合,包括请求、响应和错误拦截器管理器。
|
|
|
171
174
|
|
|
172
175
|
#### 属性
|
|
173
176
|
|
|
174
|
-
- `request:
|
|
175
|
-
- `response:
|
|
176
|
-
- `error:
|
|
177
|
+
- `request: InterceptorManager` - 请求拦截器管理器
|
|
178
|
+
- `response: InterceptorManager` - 响应拦截器管理器
|
|
179
|
+
- `error: InterceptorManager` - 错误拦截器管理器
|
|
177
180
|
|
|
178
181
|
## 完整示例
|
|
179
182
|
|
|
@@ -191,38 +194,37 @@ const fetcher = new Fetcher({
|
|
|
191
194
|
|
|
192
195
|
// 添加请求拦截器 - 添加认证头部
|
|
193
196
|
fetcher.interceptors.request.use({
|
|
194
|
-
intercept(
|
|
197
|
+
intercept(exchange) {
|
|
195
198
|
return {
|
|
196
|
-
...
|
|
197
|
-
|
|
198
|
-
...request
|
|
199
|
-
|
|
199
|
+
...exchange,
|
|
200
|
+
request: {
|
|
201
|
+
...exchange.request,
|
|
202
|
+
headers: {
|
|
203
|
+
...exchange.request.headers,
|
|
204
|
+
Authorization: 'Bearer ' + getAuthToken(),
|
|
205
|
+
},
|
|
200
206
|
},
|
|
201
207
|
};
|
|
202
208
|
},
|
|
203
209
|
});
|
|
204
210
|
|
|
205
|
-
// 添加响应拦截器 -
|
|
211
|
+
// 添加响应拦截器 - 处理响应
|
|
206
212
|
fetcher.interceptors.response.use({
|
|
207
|
-
intercept(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return new Response(JSON.stringify(data), response);
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
return response;
|
|
213
|
+
intercept(exchange) {
|
|
214
|
+
// 注意:响应处理通常在收到响应后进行
|
|
215
|
+
return exchange;
|
|
214
216
|
},
|
|
215
217
|
});
|
|
216
218
|
|
|
217
219
|
// 添加错误拦截器 - 统一错误处理
|
|
218
220
|
fetcher.interceptors.error.use({
|
|
219
|
-
intercept(
|
|
220
|
-
if (error
|
|
221
|
-
console.error('请求超时:', error.message);
|
|
221
|
+
intercept(exchange) {
|
|
222
|
+
if (exchange.error?.name === 'FetchTimeoutError') {
|
|
223
|
+
console.error('请求超时:', exchange.error.message);
|
|
222
224
|
} else {
|
|
223
|
-
console.error('网络错误:', error
|
|
225
|
+
console.error('网络错误:', exchange.error?.message);
|
|
224
226
|
}
|
|
225
|
-
return
|
|
227
|
+
return exchange;
|
|
226
228
|
},
|
|
227
229
|
});
|
|
228
230
|
|
package/dist/fetcher.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { TimeoutCapable } from './timeout';
|
|
2
2
|
import { BaseURLCapable, HeadersCapable, RequestField } from './types';
|
|
3
|
-
import { FetcherInterceptors } from './interceptor';
|
|
3
|
+
import { FetcherInterceptors, FetchExchange } from './interceptor';
|
|
4
4
|
/**
|
|
5
|
-
* Fetcher
|
|
5
|
+
* Fetcher configuration options interface
|
|
6
6
|
*/
|
|
7
7
|
export interface FetcherOptions extends BaseURLCapable, HeadersCapable, TimeoutCapable {
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Fetcher
|
|
10
|
+
* Fetcher request options interface
|
|
11
11
|
*/
|
|
12
12
|
export interface FetcherRequest extends TimeoutCapable, Omit<RequestInit, 'body'> {
|
|
13
13
|
pathParams?: Record<string, any>;
|
|
@@ -15,7 +15,7 @@ export interface FetcherRequest extends TimeoutCapable, Omit<RequestInit, 'body'
|
|
|
15
15
|
body?: BodyInit | Record<string, any> | null;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* HTTP
|
|
18
|
+
* HTTP client class that supports URL building, timeout control, and more
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
21
|
* const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
|
|
@@ -31,85 +31,104 @@ export declare class Fetcher implements HeadersCapable, TimeoutCapable {
|
|
|
31
31
|
private urlBuilder;
|
|
32
32
|
interceptors: FetcherInterceptors;
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* Create a Fetcher instance
|
|
35
35
|
*
|
|
36
|
-
* @param options - Fetcher
|
|
36
|
+
* @param options - Fetcher configuration options
|
|
37
37
|
*/
|
|
38
38
|
constructor(options?: FetcherOptions);
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* Make an HTTP request
|
|
41
41
|
*
|
|
42
|
-
* @param url -
|
|
43
|
-
* @param request -
|
|
44
|
-
* @returns Promise<Response> HTTP
|
|
42
|
+
* @param url - Request URL path
|
|
43
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
44
|
+
* @returns Promise<Response> HTTP response
|
|
45
45
|
*/
|
|
46
46
|
fetch(url: string, request?: FetcherRequest): Promise<Response>;
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* Send an HTTP request
|
|
49
49
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
50
|
+
* @param url - Request URL address, supports path parameter placeholders
|
|
51
|
+
* @param request - Request configuration object, including method, headers, body, etc.
|
|
52
|
+
* @returns Promise that resolves to a FetchExchange object containing request and response information
|
|
52
53
|
*
|
|
53
|
-
* @
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
* @throws Throws an exception when an error occurs during the request and is not handled by error interceptors
|
|
55
|
+
*/
|
|
56
|
+
request(url: string, request?: FetcherRequest): Promise<FetchExchange>;
|
|
57
|
+
/**
|
|
58
|
+
* HTTP request method with timeout control
|
|
59
|
+
*
|
|
60
|
+
* This method uses Promise.race to implement timeout control, initiating both
|
|
61
|
+
* fetch request and timeout Promise simultaneously. When either Promise completes,
|
|
62
|
+
* it returns the result or throws an exception.
|
|
63
|
+
*
|
|
64
|
+
* @param exchange - The exchange containing request information
|
|
65
|
+
* @returns Promise<Response> HTTP response Promise
|
|
66
|
+
* @throws FetchTimeoutError Thrown when the request times out
|
|
57
67
|
*/
|
|
58
68
|
private timeoutFetch;
|
|
59
69
|
/**
|
|
60
|
-
*
|
|
70
|
+
* Make an HTTP request with the specified method
|
|
71
|
+
*
|
|
72
|
+
* @param method - HTTP method to use
|
|
73
|
+
* @param url - Request URL path
|
|
74
|
+
* @param request - Request options
|
|
75
|
+
* @returns Promise<Response> HTTP response
|
|
76
|
+
*/
|
|
77
|
+
private methodFetch;
|
|
78
|
+
/**
|
|
79
|
+
* Make a GET request
|
|
61
80
|
*
|
|
62
|
-
* @param url -
|
|
63
|
-
* @param request -
|
|
64
|
-
* @returns Promise<Response> HTTP
|
|
81
|
+
* @param url - Request URL path
|
|
82
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
83
|
+
* @returns Promise<Response> HTTP response
|
|
65
84
|
*/
|
|
66
85
|
get(url: string, request?: Omit<FetcherRequest, RequestField.METHOD | RequestField.BODY>): Promise<Response>;
|
|
67
86
|
/**
|
|
68
|
-
*
|
|
87
|
+
* Make a POST request
|
|
69
88
|
*
|
|
70
|
-
* @param url -
|
|
71
|
-
* @param request -
|
|
72
|
-
* @returns Promise<Response> HTTP
|
|
89
|
+
* @param url - Request URL path
|
|
90
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
91
|
+
* @returns Promise<Response> HTTP response
|
|
73
92
|
*/
|
|
74
93
|
post(url: string, request?: Omit<FetcherRequest, RequestField.METHOD>): Promise<Response>;
|
|
75
94
|
/**
|
|
76
|
-
*
|
|
95
|
+
* Make a PUT request
|
|
77
96
|
*
|
|
78
|
-
* @param url -
|
|
79
|
-
* @param request -
|
|
80
|
-
* @returns Promise<Response> HTTP
|
|
97
|
+
* @param url - Request URL path
|
|
98
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
99
|
+
* @returns Promise<Response> HTTP response
|
|
81
100
|
*/
|
|
82
101
|
put(url: string, request?: Omit<FetcherRequest, RequestField.METHOD>): Promise<Response>;
|
|
83
102
|
/**
|
|
84
|
-
*
|
|
103
|
+
* Make a DELETE request
|
|
85
104
|
*
|
|
86
|
-
* @param url -
|
|
87
|
-
* @param request -
|
|
88
|
-
* @returns Promise<Response> HTTP
|
|
105
|
+
* @param url - Request URL path
|
|
106
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
107
|
+
* @returns Promise<Response> HTTP response
|
|
89
108
|
*/
|
|
90
109
|
delete(url: string, request?: Omit<FetcherRequest, RequestField.METHOD>): Promise<Response>;
|
|
91
110
|
/**
|
|
92
|
-
*
|
|
111
|
+
* Make a PATCH request
|
|
93
112
|
*
|
|
94
|
-
* @param url -
|
|
95
|
-
* @param request -
|
|
96
|
-
* @returns Promise<Response> HTTP
|
|
113
|
+
* @param url - Request URL path
|
|
114
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
115
|
+
* @returns Promise<Response> HTTP response
|
|
97
116
|
*/
|
|
98
117
|
patch(url: string, request?: Omit<FetcherRequest, RequestField.METHOD>): Promise<Response>;
|
|
99
118
|
/**
|
|
100
|
-
*
|
|
119
|
+
* Make a HEAD request
|
|
101
120
|
*
|
|
102
|
-
* @param url -
|
|
103
|
-
* @param request -
|
|
104
|
-
* @returns Promise<Response> HTTP
|
|
121
|
+
* @param url - Request URL path
|
|
122
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
123
|
+
* @returns Promise<Response> HTTP response
|
|
105
124
|
*/
|
|
106
125
|
head(url: string, request?: Omit<FetcherRequest, RequestField.METHOD | RequestField.BODY>): Promise<Response>;
|
|
107
126
|
/**
|
|
108
|
-
*
|
|
127
|
+
* Make an OPTIONS request
|
|
109
128
|
*
|
|
110
|
-
* @param url -
|
|
111
|
-
* @param request -
|
|
112
|
-
* @returns Promise<Response> HTTP
|
|
129
|
+
* @param url - Request URL path
|
|
130
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
131
|
+
* @returns Promise<Response> HTTP response
|
|
113
132
|
*/
|
|
114
133
|
options(url: string, request?: Omit<FetcherRequest, RequestField.METHOD | RequestField.BODY>): Promise<Response>;
|
|
115
134
|
}
|
package/dist/fetcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAqC,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9E,OAAO,EACL,cAAc,EAGd,cAAc,EAEd,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAqC,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9E,OAAO,EACL,cAAc,EAGd,cAAc,EAEd,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnE;;GAEG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,cAAc,EACd,cAAc;CACjB;AAWD;;GAEG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED;;;;;;;;;;GAUG;AACH,qBAAa,OAAQ,YAAW,cAAc,EAAE,cAAc;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAkB;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,UAAU,CAAa;IAC/B,YAAY,EAAE,mBAAmB,CAA6B;IAE9D;;;;OAIG;gBACS,OAAO,GAAE,cAA+B;IASpD;;;;;;OAMG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQzE;;;;;;;;OAQG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC;IAgDzB;;;;;;;;;;OAUG;YACW,YAAY;IA2C1B;;;;;;;OAOG;YACW,WAAW;IAWzB;;;;;;OAMG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAM,GAC1E,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAM,GAC1E,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAM,GAC1E,OAAO,CAAC,QAAQ,CAAC;CAGrB"}
|
package/dist/index.es.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
function
|
|
1
|
+
function b(r) {
|
|
2
2
|
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(r);
|
|
3
3
|
}
|
|
4
|
-
function
|
|
5
|
-
return
|
|
4
|
+
function E(r, e) {
|
|
5
|
+
return b(e) ? e : e ? r.replace(/\/?\/$/, "") + "/" + e.replace(/^\/+/, "") : r;
|
|
6
6
|
}
|
|
7
|
-
class
|
|
7
|
+
class w {
|
|
8
8
|
/**
|
|
9
9
|
* 创建UrlBuilder实例
|
|
10
10
|
*
|
|
@@ -22,13 +22,13 @@ class E {
|
|
|
22
22
|
* @returns 完整的URL字符串
|
|
23
23
|
* @throws 当路径参数中缺少必需的占位符时抛出错误
|
|
24
24
|
*/
|
|
25
|
-
build(e, t,
|
|
26
|
-
let
|
|
27
|
-
if (
|
|
28
|
-
const
|
|
29
|
-
|
|
25
|
+
build(e, t, s) {
|
|
26
|
+
let o = E(this.baseURL, e), i = this.interpolateUrl(o, t);
|
|
27
|
+
if (s) {
|
|
28
|
+
const n = new URLSearchParams(s).toString();
|
|
29
|
+
n && (i += "?" + n);
|
|
30
30
|
}
|
|
31
|
-
return
|
|
31
|
+
return i;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* 替换url中的占位符参数
|
|
@@ -39,26 +39,26 @@ class E {
|
|
|
39
39
|
* @throws 当路径参数中缺少必需的占位符时抛出错误
|
|
40
40
|
*/
|
|
41
41
|
interpolateUrl(e, t) {
|
|
42
|
-
return t ? e.replace(/{([^}]+)}/g, (
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
throw new Error(`Missing required path parameter: ${
|
|
46
|
-
return String(
|
|
42
|
+
return t ? e.replace(/{([^}]+)}/g, (s, o) => {
|
|
43
|
+
const i = t[o];
|
|
44
|
+
if (i === void 0)
|
|
45
|
+
throw new Error(`Missing required path parameter: ${o}`);
|
|
46
|
+
return String(i);
|
|
47
47
|
}) : e;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
function P(r, e) {
|
|
51
51
|
return typeof r < "u" ? r : e;
|
|
52
52
|
}
|
|
53
|
-
class
|
|
54
|
-
constructor(e, t
|
|
55
|
-
const s = `Request timeout of ${
|
|
56
|
-
super(
|
|
53
|
+
class l extends Error {
|
|
54
|
+
constructor(e, t) {
|
|
55
|
+
const s = e.request?.method || "GET", o = `Request timeout of ${t}ms exceeded for ${s} ${e.url}`;
|
|
56
|
+
super(o), this.name = "FetchTimeoutError", this.exchange = e, Object.setPrototypeOf(this, l.prototype);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
var c = /* @__PURE__ */ ((r) => (r.GET = "GET", r.POST = "POST", r.PUT = "PUT", r.DELETE = "DELETE", r.PATCH = "PATCH", r.HEAD = "HEAD", r.OPTIONS = "OPTIONS", r))(c || {}), O = /* @__PURE__ */ ((r) => (r.METHOD = "method", r.BODY = "body", r))(O || {});
|
|
60
60
|
const d = "Content-Type";
|
|
61
|
-
var
|
|
61
|
+
var f = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(f || {});
|
|
62
62
|
class h {
|
|
63
63
|
constructor() {
|
|
64
64
|
this.interceptors = [];
|
|
@@ -87,17 +87,17 @@ class h {
|
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
89
|
* 依次执行所有拦截器对数据的处理
|
|
90
|
-
* @param
|
|
90
|
+
* @param exchange - 需要处理的数据
|
|
91
91
|
* @returns 经过所有拦截器处理后的数据
|
|
92
92
|
*/
|
|
93
93
|
async intercept(e) {
|
|
94
94
|
let t = e;
|
|
95
|
-
for (let
|
|
96
|
-
|
|
95
|
+
for (let s of this.interceptors)
|
|
96
|
+
s && (t = await s.intercept(t));
|
|
97
97
|
return t;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
class
|
|
100
|
+
class q {
|
|
101
101
|
constructor() {
|
|
102
102
|
this.request = new h(), this.response = new h(), this.error = new h();
|
|
103
103
|
}
|
|
@@ -122,206 +122,223 @@ class A {
|
|
|
122
122
|
*
|
|
123
123
|
* 对于不支持的 object 类型(如普通对象),将自动转换为 JSON 字符串
|
|
124
124
|
*
|
|
125
|
-
* @param
|
|
125
|
+
* @param exchange
|
|
126
126
|
* @returns 转换后的请求
|
|
127
127
|
*/
|
|
128
128
|
intercept(e) {
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
const t = e.request;
|
|
130
|
+
if (t.body === void 0 || t.body === null || typeof t.body != "object" || t.body instanceof ArrayBuffer || ArrayBuffer.isView(t.body) || // 包括 TypedArray 和 DataView
|
|
131
|
+
t.body instanceof Blob || t.body instanceof File || t.body instanceof URLSearchParams || t.body instanceof FormData || t.body instanceof ReadableStream)
|
|
131
132
|
return e;
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
return
|
|
133
|
+
const s = { ...t };
|
|
134
|
+
s.body = JSON.stringify(t.body), s.headers || (s.headers = {});
|
|
135
|
+
const o = s.headers;
|
|
136
|
+
return o[d] || (o[d] = f.APPLICATION_JSON), { ...e, request: s };
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
|
-
const
|
|
139
|
-
[d]:
|
|
139
|
+
const m = {
|
|
140
|
+
[d]: f.APPLICATION_JSON
|
|
140
141
|
}, S = {
|
|
141
142
|
baseURL: "",
|
|
142
|
-
headers:
|
|
143
|
+
headers: m
|
|
143
144
|
};
|
|
144
145
|
class I {
|
|
145
146
|
/**
|
|
146
|
-
*
|
|
147
|
+
* Create a Fetcher instance
|
|
147
148
|
*
|
|
148
|
-
* @param options - Fetcher
|
|
149
|
+
* @param options - Fetcher configuration options
|
|
149
150
|
*/
|
|
150
151
|
constructor(e = S) {
|
|
151
|
-
this.headers =
|
|
152
|
+
this.headers = m, this.interceptors = new q(), this.urlBuilder = new w(e.baseURL), e.headers !== void 0 && (this.headers = e.headers), this.timeout = e.timeout, this.interceptors.request.use(new A());
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
154
|
-
*
|
|
155
|
+
* Make an HTTP request
|
|
155
156
|
*
|
|
156
|
-
* @param url -
|
|
157
|
-
* @param request -
|
|
158
|
-
* @returns Promise<Response> HTTP
|
|
157
|
+
* @param url - Request URL path
|
|
158
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
159
|
+
* @returns Promise<Response> HTTP response
|
|
159
160
|
*/
|
|
160
161
|
async fetch(e, t = {}) {
|
|
161
|
-
const
|
|
162
|
+
const s = await this.request(e, t);
|
|
163
|
+
if (!s.response)
|
|
164
|
+
throw new Error(`Request to ${s.url} failed with no response`);
|
|
165
|
+
return s.response;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Send an HTTP request
|
|
169
|
+
*
|
|
170
|
+
* @param url - Request URL address, supports path parameter placeholders
|
|
171
|
+
* @param request - Request configuration object, including method, headers, body, etc.
|
|
172
|
+
* @returns Promise that resolves to a FetchExchange object containing request and response information
|
|
173
|
+
*
|
|
174
|
+
* @throws Throws an exception when an error occurs during the request and is not handled by error interceptors
|
|
175
|
+
*/
|
|
176
|
+
async request(e, t = {}) {
|
|
177
|
+
const s = {
|
|
162
178
|
...this.headers || {},
|
|
163
179
|
...t.headers || {}
|
|
164
|
-
}
|
|
165
|
-
let s = {
|
|
180
|
+
}, o = {
|
|
166
181
|
...t,
|
|
167
|
-
headers: Object.keys(
|
|
182
|
+
headers: Object.keys(s).length > 0 ? s : void 0
|
|
183
|
+
}, i = this.urlBuilder.build(
|
|
184
|
+
e,
|
|
185
|
+
t.pathParams,
|
|
186
|
+
t.queryParams
|
|
187
|
+
);
|
|
188
|
+
let n = {
|
|
189
|
+
fetcher: this,
|
|
190
|
+
url: i,
|
|
191
|
+
request: o,
|
|
192
|
+
response: void 0,
|
|
193
|
+
error: void 0
|
|
168
194
|
};
|
|
169
195
|
try {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
e,
|
|
173
|
-
t.pathParams,
|
|
174
|
-
t.queryParams
|
|
175
|
-
), a = {
|
|
176
|
-
...s,
|
|
177
|
-
body: s.body
|
|
196
|
+
const u = {
|
|
197
|
+
...n
|
|
178
198
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
199
|
+
n = await this.interceptors.request.intercept(u), n.response = await this.timeoutFetch(n);
|
|
200
|
+
const a = {
|
|
201
|
+
...n
|
|
202
|
+
};
|
|
203
|
+
return n = await this.interceptors.response.intercept(a), n;
|
|
204
|
+
} catch (u) {
|
|
205
|
+
if (n.error = u, n = await this.interceptors.error.intercept(n), n.response)
|
|
206
|
+
return n;
|
|
207
|
+
throw n.error;
|
|
183
208
|
}
|
|
184
209
|
}
|
|
185
210
|
/**
|
|
186
|
-
*
|
|
211
|
+
* HTTP request method with timeout control
|
|
187
212
|
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
213
|
+
* This method uses Promise.race to implement timeout control, initiating both
|
|
214
|
+
* fetch request and timeout Promise simultaneously. When either Promise completes,
|
|
215
|
+
* it returns the result or throws an exception.
|
|
190
216
|
*
|
|
191
|
-
* @param
|
|
192
|
-
* @
|
|
193
|
-
* @
|
|
194
|
-
* @throws FetchTimeoutError 当请求超时时抛出
|
|
217
|
+
* @param exchange - The exchange containing request information
|
|
218
|
+
* @returns Promise<Response> HTTP response Promise
|
|
219
|
+
* @throws FetchTimeoutError Thrown when the request times out
|
|
195
220
|
*/
|
|
196
|
-
async timeoutFetch(e
|
|
197
|
-
const
|
|
198
|
-
if (!
|
|
199
|
-
return fetch(
|
|
200
|
-
const
|
|
201
|
-
...
|
|
202
|
-
signal:
|
|
221
|
+
async timeoutFetch(e) {
|
|
222
|
+
const t = e.url, s = e.request, o = s.timeout, i = P(o, this.timeout);
|
|
223
|
+
if (!i)
|
|
224
|
+
return fetch(t, s);
|
|
225
|
+
const n = new AbortController(), u = {
|
|
226
|
+
...s,
|
|
227
|
+
signal: n.signal
|
|
203
228
|
};
|
|
204
|
-
let
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
s
|
|
212
|
-
);
|
|
213
|
-
o.abort(l), y(l);
|
|
214
|
-
}, s);
|
|
229
|
+
let a = null;
|
|
230
|
+
const y = new Promise((F, T) => {
|
|
231
|
+
a = setTimeout(() => {
|
|
232
|
+
a && clearTimeout(a);
|
|
233
|
+
const p = new l(e, i);
|
|
234
|
+
n.abort(p), T(p);
|
|
235
|
+
}, i);
|
|
215
236
|
});
|
|
216
237
|
try {
|
|
217
|
-
return await Promise.race([
|
|
238
|
+
return await Promise.race([
|
|
239
|
+
fetch(t, u),
|
|
240
|
+
y
|
|
241
|
+
]);
|
|
218
242
|
} finally {
|
|
219
|
-
|
|
243
|
+
a && clearTimeout(a);
|
|
220
244
|
}
|
|
221
245
|
}
|
|
222
246
|
/**
|
|
223
|
-
*
|
|
247
|
+
* Make an HTTP request with the specified method
|
|
224
248
|
*
|
|
225
|
-
* @param
|
|
226
|
-
* @param
|
|
227
|
-
* @
|
|
249
|
+
* @param method - HTTP method to use
|
|
250
|
+
* @param url - Request URL path
|
|
251
|
+
* @param request - Request options
|
|
252
|
+
* @returns Promise<Response> HTTP response
|
|
228
253
|
*/
|
|
229
|
-
async
|
|
230
|
-
return this.fetch(
|
|
231
|
-
...
|
|
232
|
-
method:
|
|
254
|
+
async methodFetch(e, t, s = {}) {
|
|
255
|
+
return this.fetch(t, {
|
|
256
|
+
...s,
|
|
257
|
+
method: e
|
|
233
258
|
});
|
|
234
259
|
}
|
|
235
260
|
/**
|
|
236
|
-
*
|
|
261
|
+
* Make a GET request
|
|
237
262
|
*
|
|
238
|
-
* @param url -
|
|
239
|
-
* @param request -
|
|
240
|
-
* @returns Promise<Response> HTTP
|
|
263
|
+
* @param url - Request URL path
|
|
264
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
265
|
+
* @returns Promise<Response> HTTP response
|
|
266
|
+
*/
|
|
267
|
+
async get(e, t = {}) {
|
|
268
|
+
return this.methodFetch(c.GET, e, t);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Make a POST request
|
|
272
|
+
*
|
|
273
|
+
* @param url - Request URL path
|
|
274
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
275
|
+
* @returns Promise<Response> HTTP response
|
|
241
276
|
*/
|
|
242
277
|
async post(e, t = {}) {
|
|
243
|
-
return this.
|
|
244
|
-
...t,
|
|
245
|
-
method: c.POST
|
|
246
|
-
});
|
|
278
|
+
return this.methodFetch(c.POST, e, t);
|
|
247
279
|
}
|
|
248
280
|
/**
|
|
249
|
-
*
|
|
281
|
+
* Make a PUT request
|
|
250
282
|
*
|
|
251
|
-
* @param url -
|
|
252
|
-
* @param request -
|
|
253
|
-
* @returns Promise<Response> HTTP
|
|
283
|
+
* @param url - Request URL path
|
|
284
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
285
|
+
* @returns Promise<Response> HTTP response
|
|
254
286
|
*/
|
|
255
287
|
async put(e, t = {}) {
|
|
256
|
-
return this.
|
|
257
|
-
...t,
|
|
258
|
-
method: c.PUT
|
|
259
|
-
});
|
|
288
|
+
return this.methodFetch(c.PUT, e, t);
|
|
260
289
|
}
|
|
261
290
|
/**
|
|
262
|
-
*
|
|
291
|
+
* Make a DELETE request
|
|
263
292
|
*
|
|
264
|
-
* @param url -
|
|
265
|
-
* @param request -
|
|
266
|
-
* @returns Promise<Response> HTTP
|
|
293
|
+
* @param url - Request URL path
|
|
294
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
295
|
+
* @returns Promise<Response> HTTP response
|
|
267
296
|
*/
|
|
268
297
|
async delete(e, t = {}) {
|
|
269
|
-
return this.
|
|
270
|
-
...t,
|
|
271
|
-
method: c.DELETE
|
|
272
|
-
});
|
|
298
|
+
return this.methodFetch(c.DELETE, e, t);
|
|
273
299
|
}
|
|
274
300
|
/**
|
|
275
|
-
*
|
|
301
|
+
* Make a PATCH request
|
|
276
302
|
*
|
|
277
|
-
* @param url -
|
|
278
|
-
* @param request -
|
|
279
|
-
* @returns Promise<Response> HTTP
|
|
303
|
+
* @param url - Request URL path
|
|
304
|
+
* @param request - Request options, including path parameters, query parameters, request body, etc.
|
|
305
|
+
* @returns Promise<Response> HTTP response
|
|
280
306
|
*/
|
|
281
307
|
async patch(e, t = {}) {
|
|
282
|
-
return this.
|
|
283
|
-
...t,
|
|
284
|
-
method: c.PATCH
|
|
285
|
-
});
|
|
308
|
+
return this.methodFetch(c.PATCH, e, t);
|
|
286
309
|
}
|
|
287
310
|
/**
|
|
288
|
-
*
|
|
311
|
+
* Make a HEAD request
|
|
289
312
|
*
|
|
290
|
-
* @param url -
|
|
291
|
-
* @param request -
|
|
292
|
-
* @returns Promise<Response> HTTP
|
|
313
|
+
* @param url - Request URL path
|
|
314
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
315
|
+
* @returns Promise<Response> HTTP response
|
|
293
316
|
*/
|
|
294
317
|
async head(e, t = {}) {
|
|
295
|
-
return this.
|
|
296
|
-
...t,
|
|
297
|
-
method: c.HEAD
|
|
298
|
-
});
|
|
318
|
+
return this.methodFetch(c.HEAD, e, t);
|
|
299
319
|
}
|
|
300
320
|
/**
|
|
301
|
-
*
|
|
321
|
+
* Make an OPTIONS request
|
|
302
322
|
*
|
|
303
|
-
* @param url -
|
|
304
|
-
* @param request -
|
|
305
|
-
* @returns Promise<Response> HTTP
|
|
323
|
+
* @param url - Request URL path
|
|
324
|
+
* @param request - Request options, including path parameters, query parameters, etc.
|
|
325
|
+
* @returns Promise<Response> HTTP response
|
|
306
326
|
*/
|
|
307
327
|
async options(e, t = {}) {
|
|
308
|
-
return this.
|
|
309
|
-
...t,
|
|
310
|
-
method: c.OPTIONS
|
|
311
|
-
});
|
|
328
|
+
return this.methodFetch(c.OPTIONS, e, t);
|
|
312
329
|
}
|
|
313
330
|
}
|
|
314
331
|
export {
|
|
315
332
|
d as ContentTypeHeader,
|
|
316
|
-
|
|
317
|
-
|
|
333
|
+
f as ContentTypeValues,
|
|
334
|
+
l as FetchTimeoutError,
|
|
318
335
|
I as Fetcher,
|
|
319
|
-
|
|
336
|
+
q as FetcherInterceptors,
|
|
320
337
|
c as HttpMethod,
|
|
321
338
|
h as InterceptorManager,
|
|
322
339
|
O as RequestField,
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
340
|
+
w as UrlBuilder,
|
|
341
|
+
E as combineURLs,
|
|
342
|
+
b as isAbsoluteURL,
|
|
326
343
|
P as resolveTimeout
|
|
327
344
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(o,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(o=typeof globalThis<"u"?globalThis:o||self,h(o.Fetcher={}))})(this,(function(o){"use strict";function h(r){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(r)}function y(r,e){return h(e)?e:e?r.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):r}class T{constructor(e){this.baseURL=e}build(e,t,s){let i=y(this.baseURL,e),c=this.interpolateUrl(i,t);if(s){const n=new URLSearchParams(s).toString();n&&(c+="?"+n)}return c}interpolateUrl(e,t){return t?e.replace(/{([^}]+)}/g,(s,i)=>{const c=t[i];if(c===void 0)throw new Error(`Missing required path parameter: ${i}`);return String(c)}):e}}function b(r,e){return typeof r<"u"?r:e}class l extends Error{constructor(e,t){const s=e.request?.method||"GET",i=`Request timeout of ${t}ms exceeded for ${s} ${e.url}`;super(i),this.name="FetchTimeoutError",this.exchange=e,Object.setPrototypeOf(this,l.prototype)}}var u=(r=>(r.GET="GET",r.POST="POST",r.PUT="PUT",r.DELETE="DELETE",r.PATCH="PATCH",r.HEAD="HEAD",r.OPTIONS="OPTIONS",r))(u||{}),E=(r=>(r.METHOD="method",r.BODY="body",r))(E||{});const f="Content-Type";var m=(r=>(r.APPLICATION_JSON="application/json",r.TEXT_EVENT_STREAM="text/event-stream",r))(m||{});class p{constructor(){this.interceptors=[]}use(e){const t=this.interceptors.length;return this.interceptors.push(e),t}eject(e){this.interceptors[e]&&(this.interceptors[e]=null)}clear(){this.interceptors=[]}async intercept(e){let t=e;for(let s of this.interceptors)s&&(t=await s.intercept(t));return t}}class P{constructor(){this.request=new p,this.response=new p,this.error=new p}}class F{intercept(e){const t=e.request;if(t.body===void 0||t.body===null||typeof t.body!="object"||t.body instanceof ArrayBuffer||ArrayBuffer.isView(t.body)||t.body instanceof Blob||t.body instanceof File||t.body instanceof URLSearchParams||t.body instanceof FormData||t.body instanceof ReadableStream)return e;const s={...t};s.body=JSON.stringify(t.body),s.headers||(s.headers={});const i=s.headers;return i[f]||(i[f]=m.APPLICATION_JSON),{...e,request:s}}}const w={[f]:m.APPLICATION_JSON},S={baseURL:"",headers:w};class q{constructor(e=S){this.headers=w,this.interceptors=new P,this.urlBuilder=new T(e.baseURL),e.headers!==void 0&&(this.headers=e.headers),this.timeout=e.timeout,this.interceptors.request.use(new F)}async fetch(e,t={}){const s=await this.request(e,t);if(!s.response)throw new Error(`Request to ${s.url} failed with no response`);return s.response}async request(e,t={}){const s={...this.headers||{},...t.headers||{}},i={...t,headers:Object.keys(s).length>0?s:void 0},c=this.urlBuilder.build(e,t.pathParams,t.queryParams);let n={fetcher:this,url:c,request:i,response:void 0,error:void 0};try{const d={...n};n=await this.interceptors.request.intercept(d),n.response=await this.timeoutFetch(n);const a={...n};return n=await this.interceptors.response.intercept(a),n}catch(d){if(n.error=d,n=await this.interceptors.error.intercept(n),n.response)return n;throw n.error}}async timeoutFetch(e){const t=e.url,s=e.request,i=s.timeout,c=b(i,this.timeout);if(!c)return fetch(t,s);const n=new AbortController,d={...s,signal:n.signal};let a=null;const A=new Promise((g,U)=>{a=setTimeout(()=>{a&&clearTimeout(a);const O=new l(e,c);n.abort(O),U(O)},c)});try{return await Promise.race([fetch(t,d),A])}finally{a&&clearTimeout(a)}}async methodFetch(e,t,s={}){return this.fetch(t,{...s,method:e})}async get(e,t={}){return this.methodFetch(u.GET,e,t)}async post(e,t={}){return this.methodFetch(u.POST,e,t)}async put(e,t={}){return this.methodFetch(u.PUT,e,t)}async delete(e,t={}){return this.methodFetch(u.DELETE,e,t)}async patch(e,t={}){return this.methodFetch(u.PATCH,e,t)}async head(e,t={}){return this.methodFetch(u.HEAD,e,t)}async options(e,t={}){return this.methodFetch(u.OPTIONS,e,t)}}o.ContentTypeHeader=f,o.ContentTypeValues=m,o.FetchTimeoutError=l,o.Fetcher=q,o.FetcherInterceptors=P,o.HttpMethod=u,o.InterceptorManager=p,o.RequestField=E,o.UrlBuilder=T,o.combineURLs=y,o.isAbsoluteURL=h,o.resolveTimeout=b,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/interceptor.d.ts
CHANGED
|
@@ -1,44 +1,34 @@
|
|
|
1
|
-
import { FetcherRequest } from './fetcher';
|
|
1
|
+
import { Fetcher, FetcherRequest } from './fetcher';
|
|
2
|
+
export interface FetchExchange {
|
|
3
|
+
fetcher: Fetcher;
|
|
4
|
+
url: string;
|
|
5
|
+
request: FetcherRequest;
|
|
6
|
+
response: Response | undefined;
|
|
7
|
+
error: Error | any | undefined;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
* 拦截器接口,定义了拦截器的基本结构
|
|
4
11
|
* @template T - 拦截器处理的数据类型
|
|
5
12
|
*/
|
|
6
|
-
export interface Interceptor
|
|
13
|
+
export interface Interceptor {
|
|
7
14
|
/**
|
|
8
15
|
* 拦截并处理数据
|
|
9
|
-
* @param
|
|
16
|
+
* @param exchange - 需要处理的数据
|
|
10
17
|
* @returns 处理后的数据,可以是同步或异步返回
|
|
11
18
|
*/
|
|
12
|
-
intercept(
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* 请求拦截器接口,专门用于处理请求数据
|
|
16
|
-
*/
|
|
17
|
-
export interface RequestInterceptor extends Interceptor<FetcherRequest> {
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* 响应拦截器接口,专门用于处理响应数据
|
|
21
|
-
*/
|
|
22
|
-
export interface ResponseInterceptor extends Interceptor<Response> {
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* 错误拦截器接口,专门用于处理错误数据
|
|
26
|
-
*/
|
|
27
|
-
export interface ErrorInterceptor extends Interceptor<any> {
|
|
19
|
+
intercept(exchange: FetchExchange): FetchExchange | Promise<FetchExchange>;
|
|
28
20
|
}
|
|
29
21
|
/**
|
|
30
22
|
* 拦截器管理器类,用于管理同一类型的多个拦截器
|
|
31
|
-
* @template R - 拦截器处理的数据类型
|
|
32
|
-
* @template T - 拦截器类型
|
|
33
23
|
*/
|
|
34
|
-
export declare class InterceptorManager
|
|
24
|
+
export declare class InterceptorManager implements Interceptor {
|
|
35
25
|
private interceptors;
|
|
36
26
|
/**
|
|
37
27
|
* 添加拦截器到管理器中
|
|
38
28
|
* @param interceptor - 要添加的拦截器
|
|
39
29
|
* @returns 拦截器在管理器中的索引位置
|
|
40
30
|
*/
|
|
41
|
-
use(interceptor:
|
|
31
|
+
use(interceptor: Interceptor): number;
|
|
42
32
|
/**
|
|
43
33
|
* 根据索引移除拦截器
|
|
44
34
|
* @param index - 要移除的拦截器索引
|
|
@@ -50,23 +40,11 @@ export declare class InterceptorManager<R, T extends Interceptor<R>> implements
|
|
|
50
40
|
clear(): void;
|
|
51
41
|
/**
|
|
52
42
|
* 依次执行所有拦截器对数据的处理
|
|
53
|
-
* @param
|
|
43
|
+
* @param exchange - 需要处理的数据
|
|
54
44
|
* @returns 经过所有拦截器处理后的数据
|
|
55
45
|
*/
|
|
56
|
-
intercept(
|
|
46
|
+
intercept(exchange: FetchExchange): Promise<FetchExchange>;
|
|
57
47
|
}
|
|
58
|
-
/**
|
|
59
|
-
* 请求拦截器管理器类型定义
|
|
60
|
-
*/
|
|
61
|
-
export type RequestInterceptorManager = InterceptorManager<FetcherRequest, RequestInterceptor>;
|
|
62
|
-
/**
|
|
63
|
-
* 响应拦截器管理器类型定义
|
|
64
|
-
*/
|
|
65
|
-
export type ResponseInterceptorManager = InterceptorManager<Response, ResponseInterceptor>;
|
|
66
|
-
/**
|
|
67
|
-
* 错误拦截器管理器类型定义
|
|
68
|
-
*/
|
|
69
|
-
export type ErrorInterceptorManager = InterceptorManager<any, ErrorInterceptor>;
|
|
70
48
|
/**
|
|
71
49
|
* Fetcher拦截器集合类,包含请求、响应和错误拦截器管理器
|
|
72
50
|
*/
|
|
@@ -74,14 +52,14 @@ export declare class FetcherInterceptors {
|
|
|
74
52
|
/**
|
|
75
53
|
* 请求拦截器管理器
|
|
76
54
|
*/
|
|
77
|
-
request:
|
|
55
|
+
request: InterceptorManager;
|
|
78
56
|
/**
|
|
79
57
|
* 响应拦截器管理器
|
|
80
58
|
*/
|
|
81
|
-
response:
|
|
59
|
+
response: InterceptorManager;
|
|
82
60
|
/**
|
|
83
61
|
* 错误拦截器管理器
|
|
84
62
|
*/
|
|
85
|
-
error:
|
|
63
|
+
error: InterceptorManager;
|
|
86
64
|
}
|
|
87
65
|
//# sourceMappingURL=interceptor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC5E;AAED;;GAEG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD,OAAO,CAAC,YAAY,CAAiC;IAErD;;;;OAIG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM;IAMrC;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;OAIG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAUjE;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAA4B;IAEvD;;OAEG;IACH,QAAQ,EAAE,kBAAkB,CAA4B;IAExD;;OAEG;IACH,KAAK,EAAE,kBAAkB,CAA4B;CACtD"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FetcherRequest } from './fetcher';
|
|
1
|
+
import { FetchExchange, Interceptor } from './interceptor';
|
|
3
2
|
/**
|
|
4
3
|
* 请求体拦截器,负责将普通对象转换为JSON字符串
|
|
5
4
|
*/
|
|
6
|
-
export declare class RequestBodyInterceptor implements
|
|
5
|
+
export declare class RequestBodyInterceptor implements Interceptor {
|
|
7
6
|
/**
|
|
8
7
|
* 尝试转换请求体为合法的 fetch API body 类型
|
|
9
8
|
*
|
|
@@ -23,9 +22,9 @@ export declare class RequestBodyInterceptor implements RequestInterceptor {
|
|
|
23
22
|
*
|
|
24
23
|
* 对于不支持的 object 类型(如普通对象),将自动转换为 JSON 字符串
|
|
25
24
|
*
|
|
26
|
-
* @param
|
|
25
|
+
* @param exchange
|
|
27
26
|
* @returns 转换后的请求
|
|
28
27
|
*/
|
|
29
|
-
intercept(
|
|
28
|
+
intercept(exchange: FetchExchange): FetchExchange;
|
|
30
29
|
}
|
|
31
30
|
//# sourceMappingURL=requestBodyInterceptor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestBodyInterceptor.d.ts","sourceRoot":"","sources":["../src/requestBodyInterceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"requestBodyInterceptor.d.ts","sourceRoot":"","sources":["../src/requestBodyInterceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG3D;;GAEG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IACxD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa;CA2ClD"}
|
package/dist/timeout.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FetchExchange } from './interceptor';
|
|
2
2
|
/**
|
|
3
3
|
* 定义具有超时能力的接口
|
|
4
4
|
*/
|
|
@@ -22,8 +22,7 @@ export declare function resolveTimeout(requestTimeout?: number, optionsTimeout?:
|
|
|
22
22
|
* 当HTTP请求超时时抛出此异常
|
|
23
23
|
*/
|
|
24
24
|
export declare class FetchTimeoutError extends Error {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
constructor(url: string, request: FetcherRequest, timeout: number);
|
|
25
|
+
exchange: FetchExchange;
|
|
26
|
+
constructor(exchange: FetchExchange, timeout: number);
|
|
28
27
|
}
|
|
29
28
|
//# sourceMappingURL=timeout.d.ts.map
|
package/dist/timeout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,cAAc,CAAC,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAKpB;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,EAAE,aAAa,CAAC;gBAEZ,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;CAUrD"}
|