@ahoo-wang/fetcher 0.8.1 → 0.8.2
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 +27 -223
- package/README.zh-CN.md +132 -34
- package/dist/fetchExchange.d.ts +163 -0
- package/dist/fetchExchange.d.ts.map +1 -0
- package/dist/fetchInterceptor.d.ts +2 -1
- package/dist/fetchInterceptor.d.ts.map +1 -1
- package/dist/fetcher.d.ts +22 -86
- package/dist/fetcher.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +127 -89
- package/dist/index.umd.js +1 -1
- package/dist/interceptor.d.ts +6 -79
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/mergeRequest.d.ts +1 -1
- package/dist/mergeRequest.d.ts.map +1 -1
- package/dist/requestBodyInterceptor.d.ts +7 -4
- package/dist/requestBodyInterceptor.d.ts.map +1 -1
- package/dist/urlBuilder.d.ts +3 -0
- package/dist/urlBuilder.d.ts.map +1 -1
- package/dist/urlResolveInterceptor.d.ts +39 -0
- package/dist/urlResolveInterceptor.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/fetcher.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { UrlBuilder, UrlBuilderCapable } from './urlBuilder';
|
|
1
2
|
import { TimeoutCapable } from './timeout';
|
|
2
3
|
import { BaseURLCapable, HeadersCapable, RequestField } from './types';
|
|
3
|
-
import { FetcherInterceptors
|
|
4
|
+
import { FetcherInterceptors } from './interceptor';
|
|
5
|
+
import { FetcherRequest, FetchExchange } from './fetchExchange';
|
|
4
6
|
/**
|
|
5
7
|
* Fetcher configuration options interface
|
|
6
8
|
*/
|
|
@@ -8,89 +10,6 @@ export interface FetcherOptions extends BaseURLCapable, HeadersCapable, TimeoutC
|
|
|
8
10
|
interceptors?: FetcherInterceptors;
|
|
9
11
|
}
|
|
10
12
|
export declare const DEFAULT_OPTIONS: FetcherOptions;
|
|
11
|
-
/**
|
|
12
|
-
* Fetcher request configuration interface
|
|
13
|
-
*
|
|
14
|
-
* This interface defines all the configuration options available for making HTTP requests
|
|
15
|
-
* with the Fetcher client. It extends the standard RequestInit interface while adding
|
|
16
|
-
* Fetcher-specific features like path parameters, query parameters, and timeout control.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* const request: FetcherRequest = {
|
|
21
|
-
* method: 'GET',
|
|
22
|
-
* path: { id: 123 },
|
|
23
|
-
* query: { include: 'profile' },
|
|
24
|
-
* headers: { 'Authorization': 'Bearer token' },
|
|
25
|
-
* timeout: 5000
|
|
26
|
-
* };
|
|
27
|
-
*
|
|
28
|
-
* const response = await fetcher.fetch('/users/{id}', request);
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export interface FetcherRequest extends TimeoutCapable, HeadersCapable, Omit<RequestInit, 'body' | 'headers'> {
|
|
32
|
-
/**
|
|
33
|
-
* Path parameters for URL templating
|
|
34
|
-
*
|
|
35
|
-
* An object containing key-value pairs that will be used to replace placeholders
|
|
36
|
-
* in the URL path. Placeholders are specified using curly braces, e.g., '/users/{id}'.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* // With URL '/users/{id}/posts/{postId}'
|
|
41
|
-
* const request = {
|
|
42
|
-
* path: { id: 123, postId: 456 }
|
|
43
|
-
* };
|
|
44
|
-
* // Results in URL: '/users/123/posts/456'
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
path?: Record<string, any>;
|
|
48
|
-
/**
|
|
49
|
-
* Query parameters for URL query string
|
|
50
|
-
*
|
|
51
|
-
* An object containing key-value pairs that will be serialized and appended
|
|
52
|
-
* to the URL as query parameters. Arrays are serialized as multiple parameters
|
|
53
|
-
* with the same name, and objects are JSON-stringified.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const request = {
|
|
58
|
-
* query: {
|
|
59
|
-
* limit: 10,
|
|
60
|
-
* filter: 'active',
|
|
61
|
-
* tags: ['important', 'urgent']
|
|
62
|
-
* }
|
|
63
|
-
* };
|
|
64
|
-
* // Results in query string: '?limit=10&filter=active&tags=important&tags=urgent'
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
query?: Record<string, any>;
|
|
68
|
-
/**
|
|
69
|
-
* Request body
|
|
70
|
-
*
|
|
71
|
-
* The body of the request. Can be a string, Blob, ArrayBuffer, FormData,
|
|
72
|
-
* URLSearchParams, or a plain object. Plain objects are automatically
|
|
73
|
-
* converted to JSON and the appropriate Content-Type header is set.
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
|
-
* ```typescript
|
|
77
|
-
* // Plain object (automatically converted to JSON)
|
|
78
|
-
* const request = {
|
|
79
|
-
* method: 'POST',
|
|
80
|
-
* body: { name: 'John', email: 'john@example.com' }
|
|
81
|
-
* };
|
|
82
|
-
*
|
|
83
|
-
* // FormData
|
|
84
|
-
* const formData = new FormData();
|
|
85
|
-
* formData.append('name', 'John');
|
|
86
|
-
* const request = {
|
|
87
|
-
* method: 'POST',
|
|
88
|
-
* body: formData
|
|
89
|
-
* };
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
|
-
body?: BodyInit | Record<string, any> | null;
|
|
93
|
-
}
|
|
94
13
|
/**
|
|
95
14
|
* HTTP client class that supports URL building, timeout control, and more
|
|
96
15
|
*
|
|
@@ -102,10 +21,10 @@ export interface FetcherRequest extends TimeoutCapable, HeadersCapable, Omit<Req
|
|
|
102
21
|
* timeout: 5000
|
|
103
22
|
* });
|
|
104
23
|
*/
|
|
105
|
-
export declare class Fetcher implements HeadersCapable, TimeoutCapable {
|
|
24
|
+
export declare class Fetcher implements UrlBuilderCapable, HeadersCapable, TimeoutCapable {
|
|
25
|
+
urlBuilder: UrlBuilder;
|
|
106
26
|
headers?: Record<string, string>;
|
|
107
27
|
timeout?: number;
|
|
108
|
-
private urlBuilder;
|
|
109
28
|
interceptors: FetcherInterceptors;
|
|
110
29
|
/**
|
|
111
30
|
* Create a Fetcher instance
|
|
@@ -131,6 +50,23 @@ export declare class Fetcher implements HeadersCapable, TimeoutCapable {
|
|
|
131
50
|
* @throws Throws an exception when an error occurs during the request and is not handled by error interceptors
|
|
132
51
|
*/
|
|
133
52
|
request(url: string, request?: FetcherRequest): Promise<FetchExchange>;
|
|
53
|
+
/**
|
|
54
|
+
* Process a fetch exchange through the interceptor chain
|
|
55
|
+
*
|
|
56
|
+
* This method orchestrates the complete request lifecycle by applying interceptors
|
|
57
|
+
* in the following order:
|
|
58
|
+
* 1. Request interceptors - to modify the outgoing request
|
|
59
|
+
* 2. Response interceptors - to process the incoming response
|
|
60
|
+
*
|
|
61
|
+
* If any error occurs during the process, error interceptors are applied to handle it.
|
|
62
|
+
* If an error interceptor produces a response, that response is returned. Otherwise,
|
|
63
|
+
* the original error is re-thrown.
|
|
64
|
+
*
|
|
65
|
+
* @param fetchExchange - The exchange object containing request, response, and metadata
|
|
66
|
+
* @returns Promise<FetchExchange> The processed exchange with final response or error
|
|
67
|
+
* @throws Error if an error occurs and is not handled by error interceptors
|
|
68
|
+
*/
|
|
69
|
+
exchange(fetchExchange: FetchExchange): Promise<FetchExchange>;
|
|
134
70
|
/**
|
|
135
71
|
* Make an HTTP request with the specified method
|
|
136
72
|
*
|
package/dist/fetcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../src/fetcher.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EACL,cAAc,EAGd,cAAc,EAEd,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,cAAc,EACd,cAAc;IAChB,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAMD,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,OAAQ,YAAW,iBAAiB,EAAE,cAAc,EAAE,cAAc;IAC/E,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAmB;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,mBAAmB,CAAC;IAElC;;;;OAIG;gBACS,OAAO,GAAE,cAAgC;IAOrD;;;;;;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;IAwBzB;;;;;;;;;;;;;;;OAeG;IACG,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBpE;;;;;;;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.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './fetcher';
|
|
2
2
|
export * from './fetcherRegistrar';
|
|
3
|
+
export * from './fetchExchange';
|
|
3
4
|
export * from './fetchInterceptor';
|
|
4
5
|
export * from './interceptor';
|
|
5
6
|
export * from './mergeRequest';
|
|
@@ -9,5 +10,6 @@ export * from './requestBodyInterceptor';
|
|
|
9
10
|
export * from './timeout';
|
|
10
11
|
export * from './types';
|
|
11
12
|
export * from './urlBuilder';
|
|
13
|
+
export * from './urlResolveInterceptor';
|
|
12
14
|
export * from './urls';
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,QAAQ,CAAC"}
|
package/dist/index.es.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
function
|
|
1
|
+
function E(r) {
|
|
2
2
|
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(r);
|
|
3
3
|
}
|
|
4
|
-
function
|
|
5
|
-
return
|
|
4
|
+
function I(r, e) {
|
|
5
|
+
return E(e) ? e : e ? r.replace(/\/?\/$/, "") + "/" + e.replace(/^\/+/, "") : r;
|
|
6
6
|
}
|
|
7
|
-
class
|
|
7
|
+
class w {
|
|
8
8
|
/**
|
|
9
9
|
* Creates a UrlBuilder instance
|
|
10
10
|
*
|
|
@@ -33,11 +33,11 @@ class I {
|
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
build(e, t, s) {
|
|
36
|
-
const
|
|
37
|
-
let o = this.interpolateUrl(
|
|
36
|
+
const n = I(this.baseURL, e);
|
|
37
|
+
let o = this.interpolateUrl(n, t);
|
|
38
38
|
if (s) {
|
|
39
|
-
const
|
|
40
|
-
|
|
39
|
+
const c = new URLSearchParams(s).toString();
|
|
40
|
+
c && (o += "?" + c);
|
|
41
41
|
}
|
|
42
42
|
return o;
|
|
43
43
|
}
|
|
@@ -57,15 +57,15 @@ class I {
|
|
|
57
57
|
* ```
|
|
58
58
|
*/
|
|
59
59
|
interpolateUrl(e, t) {
|
|
60
|
-
return t ? e.replace(/{([^}]+)}/g, (s,
|
|
61
|
-
const o = t[
|
|
60
|
+
return t ? e.replace(/{([^}]+)}/g, (s, n) => {
|
|
61
|
+
const o = t[n];
|
|
62
62
|
if (o === void 0)
|
|
63
|
-
throw new Error(`Missing required path parameter: ${
|
|
63
|
+
throw new Error(`Missing required path parameter: ${n}`);
|
|
64
64
|
return String(o);
|
|
65
65
|
}) : e;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
function
|
|
68
|
+
function A(r, e) {
|
|
69
69
|
return typeof r < "u" ? r : e;
|
|
70
70
|
}
|
|
71
71
|
class p extends Error {
|
|
@@ -77,43 +77,43 @@ class p extends Error {
|
|
|
77
77
|
* @param timeout - The timeout value in milliseconds
|
|
78
78
|
*/
|
|
79
79
|
constructor(e, t, s) {
|
|
80
|
-
const
|
|
80
|
+
const n = t.method || "GET", o = `Request timeout of ${s}ms exceeded for ${n} ${e}`;
|
|
81
81
|
super(o), this.name = "FetchTimeoutError", this.url = e, this.request = t, this.timeout = s, Object.setPrototypeOf(this, p.prototype);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
async function
|
|
84
|
+
async function F(r, e, t) {
|
|
85
85
|
if (!t)
|
|
86
86
|
return fetch(r, e);
|
|
87
|
-
const s = new AbortController(),
|
|
87
|
+
const s = new AbortController(), n = {
|
|
88
88
|
...e,
|
|
89
89
|
signal: s.signal
|
|
90
90
|
};
|
|
91
91
|
let o = null;
|
|
92
|
-
const
|
|
92
|
+
const c = new Promise((y, u) => {
|
|
93
93
|
o = setTimeout(() => {
|
|
94
94
|
o && clearTimeout(o);
|
|
95
|
-
const
|
|
96
|
-
s.abort(
|
|
95
|
+
const T = new p(r, e, t);
|
|
96
|
+
s.abort(T), u(T);
|
|
97
97
|
}, t);
|
|
98
98
|
});
|
|
99
99
|
try {
|
|
100
100
|
return await Promise.race([
|
|
101
|
-
fetch(r,
|
|
102
|
-
|
|
101
|
+
fetch(r, n),
|
|
102
|
+
c
|
|
103
103
|
]);
|
|
104
104
|
} finally {
|
|
105
105
|
o && clearTimeout(o);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
var
|
|
109
|
-
const
|
|
110
|
-
var
|
|
111
|
-
function
|
|
108
|
+
var i = /* @__PURE__ */ ((r) => (r.GET = "GET", r.POST = "POST", r.PUT = "PUT", r.DELETE = "DELETE", r.PATCH = "PATCH", r.HEAD = "HEAD", r.OPTIONS = "OPTIONS", r))(i || {}), N = /* @__PURE__ */ ((r) => (r.METHOD = "method", r.BODY = "body", r))(N || {});
|
|
109
|
+
const d = "Content-Type";
|
|
110
|
+
var f = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(f || {});
|
|
111
|
+
function a(r, e) {
|
|
112
112
|
return e ? r.filter(e).sort((t, s) => t.order - s.order) : [...r].sort((t, s) => t.order - s.order);
|
|
113
113
|
}
|
|
114
114
|
class O {
|
|
115
115
|
constructor() {
|
|
116
|
-
this.name = "RequestBodyInterceptor", this.order = Number.MIN_SAFE_INTEGER;
|
|
116
|
+
this.name = "RequestBodyInterceptor", this.order = Number.MIN_SAFE_INTEGER + 100;
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* Attempts to convert request body to a valid fetch API body type
|
|
@@ -158,8 +158,8 @@ class O {
|
|
|
158
158
|
return e;
|
|
159
159
|
const s = { ...t };
|
|
160
160
|
s.body = JSON.stringify(t.body), s.headers || (s.headers = {});
|
|
161
|
-
const
|
|
162
|
-
return
|
|
161
|
+
const n = s.headers;
|
|
162
|
+
return n[d] || (n[d] = f.APPLICATION_JSON), e.request = s, e;
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
class P {
|
|
@@ -191,14 +191,32 @@ class P {
|
|
|
191
191
|
* console.log(result.response); // HTTP response object
|
|
192
192
|
*/
|
|
193
193
|
async intercept(e) {
|
|
194
|
-
return e.response = await
|
|
194
|
+
return e.response = await F(
|
|
195
195
|
e.url,
|
|
196
196
|
e.request,
|
|
197
197
|
e.request.timeout
|
|
198
198
|
), e;
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
-
class
|
|
201
|
+
class R {
|
|
202
|
+
constructor() {
|
|
203
|
+
this.name = "UrlResolveInterceptor", this.order = Number.MIN_SAFE_INTEGER;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Resolves the final URL by combining the base URL, path parameters, and query parameters
|
|
207
|
+
*
|
|
208
|
+
* @param exchange - The fetch exchange containing the request information
|
|
209
|
+
* @returns The modified exchange with the resolved URL
|
|
210
|
+
*/
|
|
211
|
+
intercept(e) {
|
|
212
|
+
return e.url = e.fetcher.urlBuilder.build(
|
|
213
|
+
e.url,
|
|
214
|
+
e.request.path,
|
|
215
|
+
e.request.query
|
|
216
|
+
), e;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
class h {
|
|
202
220
|
/**
|
|
203
221
|
* Creates a new InterceptorManager instance
|
|
204
222
|
*
|
|
@@ -209,7 +227,7 @@ class d {
|
|
|
209
227
|
* upon construction.
|
|
210
228
|
*/
|
|
211
229
|
constructor(e = []) {
|
|
212
|
-
this.sortedInterceptors = [], this.sortedInterceptors =
|
|
230
|
+
this.sortedInterceptors = [], this.sortedInterceptors = a(e);
|
|
213
231
|
}
|
|
214
232
|
/**
|
|
215
233
|
* Gets the name of this interceptor manager
|
|
@@ -241,7 +259,7 @@ class d {
|
|
|
241
259
|
* After adding, interceptors are automatically sorted by their order property.
|
|
242
260
|
*/
|
|
243
261
|
use(e) {
|
|
244
|
-
return this.sortedInterceptors.some((t) => t.name === e.name) ? !1 : (this.sortedInterceptors =
|
|
262
|
+
return this.sortedInterceptors.some((t) => t.name === e.name) ? !1 : (this.sortedInterceptors = a([
|
|
245
263
|
...this.sortedInterceptors,
|
|
246
264
|
e
|
|
247
265
|
]), !0);
|
|
@@ -255,7 +273,7 @@ class d {
|
|
|
255
273
|
*/
|
|
256
274
|
eject(e) {
|
|
257
275
|
const t = this.sortedInterceptors;
|
|
258
|
-
return this.sortedInterceptors =
|
|
276
|
+
return this.sortedInterceptors = a(
|
|
259
277
|
t,
|
|
260
278
|
(s) => s.name !== e
|
|
261
279
|
), t.length !== this.sortedInterceptors.length;
|
|
@@ -289,26 +307,27 @@ class d {
|
|
|
289
307
|
}
|
|
290
308
|
class S {
|
|
291
309
|
constructor() {
|
|
292
|
-
this.request = new
|
|
310
|
+
this.request = new h([
|
|
311
|
+
new R(),
|
|
293
312
|
new O(),
|
|
294
313
|
new P()
|
|
295
|
-
]), this.response = new
|
|
314
|
+
]), this.response = new h(), this.error = new h();
|
|
296
315
|
}
|
|
297
316
|
}
|
|
298
|
-
const
|
|
299
|
-
[
|
|
300
|
-
},
|
|
317
|
+
const l = {
|
|
318
|
+
[d]: f.APPLICATION_JSON
|
|
319
|
+
}, b = {
|
|
301
320
|
baseURL: "",
|
|
302
|
-
headers:
|
|
321
|
+
headers: l
|
|
303
322
|
};
|
|
304
|
-
class
|
|
323
|
+
class g {
|
|
305
324
|
/**
|
|
306
325
|
* Create a Fetcher instance
|
|
307
326
|
*
|
|
308
327
|
* @param options - Fetcher configuration options
|
|
309
328
|
*/
|
|
310
|
-
constructor(e =
|
|
311
|
-
this.headers =
|
|
329
|
+
constructor(e = b) {
|
|
330
|
+
this.headers = l, this.urlBuilder = new w(e.baseURL), this.headers = e.headers ?? l, this.timeout = e.timeout, this.interceptors = e.interceptors ?? new S();
|
|
312
331
|
}
|
|
313
332
|
/**
|
|
314
333
|
* Make an HTTP request
|
|
@@ -336,25 +355,43 @@ class N {
|
|
|
336
355
|
const s = {
|
|
337
356
|
...this.headers || {},
|
|
338
357
|
...t.headers || {}
|
|
339
|
-
},
|
|
358
|
+
}, n = {
|
|
340
359
|
...t,
|
|
341
360
|
headers: Object.keys(s).length > 0 ? s : void 0,
|
|
342
|
-
timeout:
|
|
343
|
-
}, o =
|
|
344
|
-
let n = {
|
|
361
|
+
timeout: A(t.timeout, this.timeout)
|
|
362
|
+
}, o = {
|
|
345
363
|
fetcher: this,
|
|
346
|
-
url:
|
|
347
|
-
request:
|
|
364
|
+
url: e,
|
|
365
|
+
request: n,
|
|
348
366
|
response: void 0,
|
|
349
367
|
error: void 0,
|
|
350
368
|
attributes: {}
|
|
351
369
|
};
|
|
370
|
+
return this.exchange(o);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Process a fetch exchange through the interceptor chain
|
|
374
|
+
*
|
|
375
|
+
* This method orchestrates the complete request lifecycle by applying interceptors
|
|
376
|
+
* in the following order:
|
|
377
|
+
* 1. Request interceptors - to modify the outgoing request
|
|
378
|
+
* 2. Response interceptors - to process the incoming response
|
|
379
|
+
*
|
|
380
|
+
* If any error occurs during the process, error interceptors are applied to handle it.
|
|
381
|
+
* If an error interceptor produces a response, that response is returned. Otherwise,
|
|
382
|
+
* the original error is re-thrown.
|
|
383
|
+
*
|
|
384
|
+
* @param fetchExchange - The exchange object containing request, response, and metadata
|
|
385
|
+
* @returns Promise<FetchExchange> The processed exchange with final response or error
|
|
386
|
+
* @throws Error if an error occurs and is not handled by error interceptors
|
|
387
|
+
*/
|
|
388
|
+
async exchange(e) {
|
|
352
389
|
try {
|
|
353
|
-
return
|
|
354
|
-
} catch (
|
|
355
|
-
if (
|
|
356
|
-
return
|
|
357
|
-
throw
|
|
390
|
+
return e = await this.interceptors.request.intercept(e), e = await this.interceptors.response.intercept(e), e;
|
|
391
|
+
} catch (t) {
|
|
392
|
+
if (e.error = t, e = await this.interceptors.error.intercept(e), e.response)
|
|
393
|
+
return e;
|
|
394
|
+
throw e.error;
|
|
358
395
|
}
|
|
359
396
|
}
|
|
360
397
|
/**
|
|
@@ -379,7 +416,7 @@ class N {
|
|
|
379
416
|
* @returns Promise<Response> HTTP response
|
|
380
417
|
*/
|
|
381
418
|
async get(e, t = {}) {
|
|
382
|
-
return this.methodFetch(
|
|
419
|
+
return this.methodFetch(i.GET, e, t);
|
|
383
420
|
}
|
|
384
421
|
/**
|
|
385
422
|
* Make a POST request
|
|
@@ -389,7 +426,7 @@ class N {
|
|
|
389
426
|
* @returns Promise<Response> HTTP response
|
|
390
427
|
*/
|
|
391
428
|
async post(e, t = {}) {
|
|
392
|
-
return this.methodFetch(
|
|
429
|
+
return this.methodFetch(i.POST, e, t);
|
|
393
430
|
}
|
|
394
431
|
/**
|
|
395
432
|
* Make a PUT request
|
|
@@ -399,7 +436,7 @@ class N {
|
|
|
399
436
|
* @returns Promise<Response> HTTP response
|
|
400
437
|
*/
|
|
401
438
|
async put(e, t = {}) {
|
|
402
|
-
return this.methodFetch(
|
|
439
|
+
return this.methodFetch(i.PUT, e, t);
|
|
403
440
|
}
|
|
404
441
|
/**
|
|
405
442
|
* Make a DELETE request
|
|
@@ -409,7 +446,7 @@ class N {
|
|
|
409
446
|
* @returns Promise<Response> HTTP response
|
|
410
447
|
*/
|
|
411
448
|
async delete(e, t = {}) {
|
|
412
|
-
return this.methodFetch(
|
|
449
|
+
return this.methodFetch(i.DELETE, e, t);
|
|
413
450
|
}
|
|
414
451
|
/**
|
|
415
452
|
* Make a PATCH request
|
|
@@ -419,7 +456,7 @@ class N {
|
|
|
419
456
|
* @returns Promise<Response> HTTP response
|
|
420
457
|
*/
|
|
421
458
|
async patch(e, t = {}) {
|
|
422
|
-
return this.methodFetch(
|
|
459
|
+
return this.methodFetch(i.PATCH, e, t);
|
|
423
460
|
}
|
|
424
461
|
/**
|
|
425
462
|
* Make a HEAD request
|
|
@@ -429,7 +466,7 @@ class N {
|
|
|
429
466
|
* @returns Promise<Response> HTTP response
|
|
430
467
|
*/
|
|
431
468
|
async head(e, t = {}) {
|
|
432
|
-
return this.methodFetch(
|
|
469
|
+
return this.methodFetch(i.HEAD, e, t);
|
|
433
470
|
}
|
|
434
471
|
/**
|
|
435
472
|
* Make an OPTIONS request
|
|
@@ -439,11 +476,11 @@ class N {
|
|
|
439
476
|
* @returns Promise<Response> HTTP response
|
|
440
477
|
*/
|
|
441
478
|
async options(e, t = {}) {
|
|
442
|
-
return this.methodFetch(
|
|
479
|
+
return this.methodFetch(i.OPTIONS, e, t);
|
|
443
480
|
}
|
|
444
481
|
}
|
|
445
482
|
const m = "default";
|
|
446
|
-
class
|
|
483
|
+
class q {
|
|
447
484
|
constructor() {
|
|
448
485
|
this.registrar = /* @__PURE__ */ new Map();
|
|
449
486
|
}
|
|
@@ -543,8 +580,8 @@ class R {
|
|
|
543
580
|
return new Map(this.registrar);
|
|
544
581
|
}
|
|
545
582
|
}
|
|
546
|
-
const
|
|
547
|
-
function
|
|
583
|
+
const _ = new q();
|
|
584
|
+
function L(r, e) {
|
|
548
585
|
if (Object.keys(r).length === 0)
|
|
549
586
|
return e;
|
|
550
587
|
if (Object.keys(e).length === 0)
|
|
@@ -555,23 +592,23 @@ function _(r, e) {
|
|
|
555
592
|
}, s = {
|
|
556
593
|
...r.query,
|
|
557
594
|
...e.query
|
|
558
|
-
},
|
|
595
|
+
}, n = {
|
|
559
596
|
...r.headers,
|
|
560
597
|
...e.headers
|
|
561
|
-
}, o = e.method ?? r.method,
|
|
598
|
+
}, o = e.method ?? r.method, c = e.body ?? r.body, y = e.timeout ?? r.timeout, u = e.signal ?? r.signal;
|
|
562
599
|
return {
|
|
563
600
|
...r,
|
|
564
601
|
...e,
|
|
565
602
|
method: o,
|
|
566
603
|
path: t,
|
|
567
604
|
query: s,
|
|
568
|
-
headers:
|
|
569
|
-
body:
|
|
570
|
-
timeout:
|
|
571
|
-
signal:
|
|
605
|
+
headers: n,
|
|
606
|
+
body: c,
|
|
607
|
+
timeout: y,
|
|
608
|
+
signal: u
|
|
572
609
|
};
|
|
573
610
|
}
|
|
574
|
-
class U extends
|
|
611
|
+
class U extends g {
|
|
575
612
|
/**
|
|
576
613
|
* Create a NamedFetcher instance and automatically register it with the global fetcherRegistrar
|
|
577
614
|
*
|
|
@@ -589,33 +626,34 @@ class U extends N {
|
|
|
589
626
|
* headers: { 'Authorization': 'Bearer token' }
|
|
590
627
|
* });
|
|
591
628
|
*/
|
|
592
|
-
constructor(e, t =
|
|
593
|
-
super(t), this.name = e,
|
|
629
|
+
constructor(e, t = b) {
|
|
630
|
+
super(t), this.name = e, _.register(e, this);
|
|
594
631
|
}
|
|
595
632
|
}
|
|
596
|
-
const
|
|
633
|
+
const D = new U(m);
|
|
597
634
|
export {
|
|
598
|
-
|
|
599
|
-
|
|
635
|
+
d as ContentTypeHeader,
|
|
636
|
+
f as ContentTypeValues,
|
|
600
637
|
m as DEFAULT_FETCHER_NAME,
|
|
601
|
-
|
|
638
|
+
b as DEFAULT_OPTIONS,
|
|
602
639
|
P as FetchInterceptor,
|
|
603
640
|
p as FetchTimeoutError,
|
|
604
|
-
|
|
641
|
+
g as Fetcher,
|
|
605
642
|
S as FetcherInterceptors,
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
643
|
+
q as FetcherRegistrar,
|
|
644
|
+
i as HttpMethod,
|
|
645
|
+
h as InterceptorManager,
|
|
609
646
|
U as NamedFetcher,
|
|
610
647
|
O as RequestBodyInterceptor,
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
A as
|
|
620
|
-
|
|
648
|
+
N as RequestField,
|
|
649
|
+
w as UrlBuilder,
|
|
650
|
+
R as UrlResolveInterceptor,
|
|
651
|
+
I as combineURLs,
|
|
652
|
+
D as fetcher,
|
|
653
|
+
_ as fetcherRegistrar,
|
|
654
|
+
E as isAbsoluteURL,
|
|
655
|
+
L as mergeRequest,
|
|
656
|
+
A as resolveTimeout,
|
|
657
|
+
F as timeoutFetch,
|
|
658
|
+
a as toSorted
|
|
621
659
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(n,
|
|
1
|
+
(function(n,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(n=typeof globalThis<"u"?globalThis:n||self,u(n.Fetcher={}))})(this,(function(n){"use strict";function u(r){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(r)}function E(r,e){return u(e)?e:e?r.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):r}class I{constructor(e){this.baseURL=e}build(e,t,s){const i=E(this.baseURL,e);let o=this.interpolateUrl(i,t);if(s){const a=new URLSearchParams(s).toString();a&&(o+="?"+a)}return o}interpolateUrl(e,t){return t?e.replace(/{([^}]+)}/g,(s,i)=>{const o=t[i];if(o===void 0)throw new Error(`Missing required path parameter: ${i}`);return String(o)}):e}}function F(r,e){return typeof r<"u"?r:e}class h extends Error{constructor(e,t,s){const i=t.method||"GET",o=`Request timeout of ${s}ms exceeded for ${i} ${e}`;super(o),this.name="FetchTimeoutError",this.url=e,this.request=t,this.timeout=s,Object.setPrototypeOf(this,h.prototype)}}async function R(r,e,t){if(!t)return fetch(r,e);const s=new AbortController,i={...e,signal:s.signal};let o=null;const a=new Promise((_,b)=>{o=setTimeout(()=>{o&&clearTimeout(o);const L=new h(r,e,t);s.abort(L),b(L)},t)});try{return await Promise.race([fetch(r,i),a])}finally{o&&clearTimeout(o)}}var c=(r=>(r.GET="GET",r.POST="POST",r.PUT="PUT",r.DELETE="DELETE",r.PATCH="PATCH",r.HEAD="HEAD",r.OPTIONS="OPTIONS",r))(c||{}),w=(r=>(r.METHOD="method",r.BODY="body",r))(w||{});const d="Content-Type";var l=(r=>(r.APPLICATION_JSON="application/json",r.TEXT_EVENT_STREAM="text/event-stream",r))(l||{});function m(r,e){return e?r.filter(e).sort((t,s)=>t.order-s.order):[...r].sort((t,s)=>t.order-s.order)}class A{constructor(){this.name="RequestBodyInterceptor",this.order=Number.MIN_SAFE_INTEGER+100}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[d]||(i[d]=l.APPLICATION_JSON),e.request=s,e}}class N{constructor(){this.name="FetchInterceptor",this.order=Number.MAX_SAFE_INTEGER}async intercept(e){return e.response=await R(e.url,e.request,e.request.timeout),e}}class O{constructor(){this.name="UrlResolveInterceptor",this.order=Number.MIN_SAFE_INTEGER}intercept(e){return e.url=e.fetcher.urlBuilder.build(e.url,e.request.path,e.request.query),e}}class f{constructor(e=[]){this.sortedInterceptors=[],this.sortedInterceptors=m(e)}get name(){return this.constructor.name}get order(){return Number.MIN_SAFE_INTEGER}use(e){return this.sortedInterceptors.some(t=>t.name===e.name)?!1:(this.sortedInterceptors=m([...this.sortedInterceptors,e]),!0)}eject(e){const t=this.sortedInterceptors;return this.sortedInterceptors=m(t,s=>s.name!==e),t.length!==this.sortedInterceptors.length}clear(){this.sortedInterceptors=[]}async intercept(e){let t=e;for(const s of this.sortedInterceptors)t=await s.intercept(t);return t}}class S{constructor(){this.request=new f([new O,new A,new N]),this.response=new f,this.error=new f}}const T={[d]:l.APPLICATION_JSON},p={baseURL:"",headers:T};class g{constructor(e=p){this.headers=T,this.urlBuilder=new I(e.baseURL),this.headers=e.headers??T,this.timeout=e.timeout,this.interceptors=e.interceptors??new S}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,timeout:F(t.timeout,this.timeout)},o={fetcher:this,url:e,request:i,response:void 0,error:void 0,attributes:{}};return this.exchange(o)}async exchange(e){try{return e=await this.interceptors.request.intercept(e),e=await this.interceptors.response.intercept(e),e}catch(t){if(e.error=t,e=await this.interceptors.error.intercept(e),e.response)return e;throw e.error}}async methodFetch(e,t,s={}){return this.fetch(t,{...s,method:e})}async get(e,t={}){return this.methodFetch(c.GET,e,t)}async post(e,t={}){return this.methodFetch(c.POST,e,t)}async put(e,t={}){return this.methodFetch(c.PUT,e,t)}async delete(e,t={}){return this.methodFetch(c.DELETE,e,t)}async patch(e,t={}){return this.methodFetch(c.PATCH,e,t)}async head(e,t={}){return this.methodFetch(c.HEAD,e,t)}async options(e,t={}){return this.methodFetch(c.OPTIONS,e,t)}}const y="default";class P{constructor(){this.registrar=new Map}register(e,t){this.registrar.set(e,t)}unregister(e){return this.registrar.delete(e)}get(e){return this.registrar.get(e)}requiredGet(e){const t=this.get(e);if(!t)throw new Error(`Fetcher ${e} not found`);return t}get default(){return this.requiredGet(y)}set default(e){this.register(y,e)}get fetchers(){return new Map(this.registrar)}}const q=new P;function D(r,e){if(Object.keys(r).length===0)return e;if(Object.keys(e).length===0)return r;const t={...r.path,...e.path},s={...r.query,...e.query},i={...r.headers,...e.headers},o=e.method??r.method,a=e.body??r.body,_=e.timeout??r.timeout,b=e.signal??r.signal;return{...r,...e,method:o,path:t,query:s,headers:i,body:a,timeout:_,signal:b}}class U extends g{constructor(e,t=p){super(t),this.name=e,q.register(e,this)}}const v=new U(y);n.ContentTypeHeader=d,n.ContentTypeValues=l,n.DEFAULT_FETCHER_NAME=y,n.DEFAULT_OPTIONS=p,n.FetchInterceptor=N,n.FetchTimeoutError=h,n.Fetcher=g,n.FetcherInterceptors=S,n.FetcherRegistrar=P,n.HttpMethod=c,n.InterceptorManager=f,n.NamedFetcher=U,n.RequestBodyInterceptor=A,n.RequestField=w,n.UrlBuilder=I,n.UrlResolveInterceptor=O,n.combineURLs=E,n.fetcher=v,n.fetcherRegistrar=q,n.isAbsoluteURL=u,n.mergeRequest=D,n.resolveTimeout=F,n.timeoutFetch=R,n.toSorted=m,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
|