@ahoo-wang/fetcher 0.8.8 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -139,14 +139,11 @@ const success = fetcher.interceptors.request.use({
139
139
  name: 'auth-interceptor',
140
140
  order: 100,
141
141
  intercept(exchange) {
142
- return {
143
- ...exchange,
144
- request: {
145
- ...exchange.request,
146
- headers: {
147
- ...exchange.request.headers,
148
- Authorization: 'Bearer ' + getAuthToken(),
149
- },
142
+ exchange.request = {
143
+ ...exchange.request,
144
+ headers: {
145
+ ...exchange.request.headers,
146
+ Authorization: 'Bearer ' + getAuthToken(),
150
147
  },
151
148
  };
152
149
  },
@@ -158,7 +155,6 @@ fetcher.interceptors.response.use({
158
155
  order: 10,
159
156
  intercept(exchange) {
160
157
  console.log('Response received:', exchange.response?.status);
161
- return exchange;
162
158
  },
163
159
  });
164
160
 
@@ -172,7 +168,6 @@ fetcher.interceptors.error.use({
172
168
  } else {
173
169
  console.error('Network error:', exchange.error?.message);
174
170
  }
175
- return exchange;
176
171
  },
177
172
  });
178
173
 
@@ -335,7 +330,7 @@ Interceptor interface that defines the basic structure of interceptors.
335
330
 
336
331
  **Methods:**
337
332
 
338
- - `intercept(exchange: FetchExchange): FetchExchange | Promise<FetchExchange>` - Intercept and process data
333
+ - `intercept(exchange: FetchExchange): void | Promise<void>` - Intercept and process data
339
334
 
340
335
  #### InterceptorManager Class
341
336
 
@@ -346,7 +341,7 @@ Interceptor manager for managing multiple interceptors of the same type.
346
341
  - `use(interceptor: Interceptor): boolean` - Add interceptor, returns whether the addition was successful
347
342
  - `eject(name: string): boolean` - Remove interceptor by name, returns whether the removal was successful
348
343
  - `clear(): void` - Clear all interceptors
349
- - `intercept(exchange: FetchExchange): Promise<FetchExchange>` - Execute all interceptors in sequence
344
+ - `intercept(exchange: FetchExchange): Promise<void>` - Execute all interceptors in sequence
350
345
 
351
346
  #### FetcherInterceptors Class
352
347
 
package/README.zh-CN.md CHANGED
@@ -137,14 +137,11 @@ const success = fetcher.interceptors.request.use({
137
137
  name: 'auth-interceptor',
138
138
  order: 100,
139
139
  intercept(exchange) {
140
- return {
141
- ...exchange,
142
- request: {
143
- ...exchange.request,
144
- headers: {
145
- ...exchange.request.headers,
146
- Authorization: 'Bearer ' + getAuthToken(),
147
- },
140
+ exchange.request = {
141
+ ...exchange.request,
142
+ headers: {
143
+ ...exchange.request.headers,
144
+ Authorization: 'Bearer ' + getAuthToken(),
148
145
  },
149
146
  };
150
147
  },
@@ -156,7 +153,6 @@ fetcher.interceptors.response.use({
156
153
  order: 10,
157
154
  intercept(exchange) {
158
155
  console.log('收到响应:', exchange.response?.status);
159
- return exchange;
160
156
  },
161
157
  });
162
158
 
@@ -170,7 +166,6 @@ fetcher.interceptors.error.use({
170
166
  } else {
171
167
  console.error('网络错误:', exchange.error?.message);
172
168
  }
173
- return exchange;
174
169
  },
175
170
  });
176
171
 
@@ -333,7 +328,7 @@ string, options ? : FetcherOptions
333
328
 
334
329
  **方法:**
335
330
 
336
- - `intercept(exchange: FetchExchange): FetchExchange | Promise<FetchExchange>` - 拦截并处理数据
331
+ - `intercept(exchange: FetchExchange): void | Promise<void>` - 拦截并处理数据
337
332
 
338
333
  #### InterceptorManager 类
339
334
 
@@ -344,7 +339,7 @@ string, options ? : FetcherOptions
344
339
  - `use(interceptor: Interceptor): boolean` - 添加拦截器,返回是否添加成功
345
340
  - `eject(name: string): boolean` - 按名称移除拦截器,返回是否移除成功
346
341
  - `clear(): void` - 清除所有拦截器
347
- - `intercept(exchange: FetchExchange): Promise<FetchExchange>` - 顺序执行所有拦截器
342
+ - `intercept(exchange: FetchExchange): Promise<void>` - 顺序执行所有拦截器
348
343
 
349
344
  #### FetcherInterceptors 类
350
345
 
@@ -1,25 +1,28 @@
1
1
  import { Fetcher } from './fetcher';
2
2
  import { FetchRequest } from './fetchRequest';
3
3
  /**
4
- * FetchExchange Interface
4
+ * FetchExchange
5
5
  *
6
6
  * Represents the complete exchange object that flows through the interceptor chain.
7
7
  * This object contains all the information about a request, response, and any errors
8
8
  * that occur during the HTTP request lifecycle. It also provides a mechanism for
9
9
  * sharing data between interceptors through the attributes property.
10
10
  *
11
+ * FetchExchange instances are unique within a single request scope, meaning each HTTP
12
+ * request creates its own FetchExchange instance that is passed through the interceptor
13
+ * chain for that specific request.
14
+ *
11
15
  * @example
12
16
  * ```typescript
13
17
  * // In a request interceptor
14
18
  * const requestInterceptor: Interceptor = {
15
19
  * name: 'RequestInterceptor',
16
20
  * order: 0,
17
- * async intercept(exchange: FetchExchange): Promise<FetchExchange> {
21
+ * intercept(exchange: FetchExchange) {
18
22
  * // Add custom data to share with other interceptors
19
23
  * exchange.attributes = exchange.attributes || {};
20
24
  * exchange.attributes.startTime = Date.now();
21
25
  * exchange.attributes.customHeader = 'my-value';
22
- * return exchange;
23
26
  * }
24
27
  * };
25
28
  *
@@ -27,19 +30,18 @@ import { FetchRequest } from './fetchRequest';
27
30
  * const responseInterceptor: Interceptor = {
28
31
  * name: 'ResponseInterceptor',
29
32
  * order: 0,
30
- * async intercept(exchange: FetchExchange): Promise<FetchExchange> {
33
+ * intercept(exchange: FetchExchange) {
31
34
  * // Access data shared by previous interceptors
32
35
  * if (exchange.attributes && exchange.attributes.startTime) {
33
36
  * const startTime = exchange.attributes.startTime;
34
37
  * const duration = Date.now() - startTime;
35
38
  * console.log(`Request took ${duration}ms`);
36
39
  * }
37
- * return exchange;
38
40
  * }
39
41
  * };
40
42
  * ```
41
43
  */
42
- export interface FetchExchange {
44
+ export declare class FetchExchange {
43
45
  /**
44
46
  * The Fetcher instance that initiated this exchange
45
47
  */
@@ -70,6 +72,19 @@ export interface FetchExchange {
70
72
  * - Consider namespacing your keys (e.g., 'mylib.retryCount' instead of 'retryCount')
71
73
  * - Be mindful of memory usage when storing large objects
72
74
  */
73
- attributes?: Record<string, any>;
75
+ attributes: Record<string, any>;
76
+ constructor(fetcher: Fetcher, request: FetchRequest, response?: Response, error?: Error | any);
77
+ /**
78
+ * Checks if the exchange has an error
79
+ *
80
+ * @returns true if an error is present, false otherwise
81
+ */
82
+ hasError(): boolean;
83
+ /**
84
+ * Checks if the exchange has a response
85
+ *
86
+ * @returns true if a response is present, false otherwise
87
+ */
88
+ hasResponse(): boolean;
74
89
  }
75
90
  //# sourceMappingURL=fetchExchange.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchExchange.d.ts","sourceRoot":"","sources":["../src/fetchExchange.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAE/B;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS,CAAC;IAE/B;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC"}
1
+ {"version":3,"file":"fetchExchange.d.ts","sourceRoot":"","sources":["../src/fetchExchange.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,aAAa;IACxB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC;IAE/B;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS,CAAC;IAE/B;;;;;;;;;;;;;OAaG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAM;gBAGnC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,EACrB,QAAQ,CAAC,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,KAAK,GAAG,GAAG;IAQrB;;;;OAIG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;OAIG;IACH,WAAW,IAAI,OAAO;CAGvB"}
@@ -41,7 +41,6 @@ export declare class FetchInterceptor implements Interceptor {
41
41
  * function to send the network request.
42
42
  *
43
43
  * @param exchange - Exchange object containing request information
44
- * @returns Promise<FetchExchange> Processed exchange object containing response information
45
44
  *
46
45
  * @throws {FetchTimeoutError} Throws timeout exception when request times out
47
46
  *
@@ -57,6 +56,6 @@ export declare class FetchInterceptor implements Interceptor {
57
56
  * const result = await fetchInterceptor.intercept(exchange);
58
57
  * console.log(result.response); // HTTP response object
59
58
  */
60
- intercept(exchange: FetchExchange): Promise<FetchExchange>;
59
+ intercept(exchange: FetchExchange): Promise<void>;
61
60
  }
62
61
  //# sourceMappingURL=fetchInterceptor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchInterceptor.d.ts","sourceRoot":"","sources":["../src/fetchInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAClD;;;;;;OAMG;IACH,IAAI,SAAsB;IAE1B;;;;;;;;;OASG;IACH,KAAK,SAAiC;IAEtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAIjE"}
1
+ {"version":3,"file":"fetchInterceptor.d.ts","sourceRoot":"","sources":["../src/fetchInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAClD;;;;;;OAMG;IACH,IAAI,SAAsB;IAE1B;;;;;;;;;OASG;IACH,KAAK,SAAiC;IAEtC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa;CAGxC"}
@@ -1 +1 @@
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,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,cAAc,EAEd,YAAY,EACZ,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAGxB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,qBAAqB,EACrB,cAAc;IAChB,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAMD,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,OACX,YAAW,iBAAiB,EAAE,qBAAqB,EAAE,cAAc;IAEnE,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAmB;IAC3C,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,gBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAU3E;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAmB5D;;;;;;;;;;;;;;;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,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;CAGrB"}
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,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,cAAc,EAEd,YAAY,EACZ,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAGxB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,qBAAqB,EACrB,cAAc;IAChB,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAMD,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,OACX,YAAW,iBAAiB,EAAE,qBAAqB,EAAE,cAAc;IACnE,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAmB;IAC3C,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,gBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAU3E;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAa5D;;;;;;;;;;;;;;;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,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;OAMG;IACG,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;CAGrB"}
package/dist/index.es.js CHANGED
@@ -1,10 +1,10 @@
1
- function b(r) {
1
+ function I(r) {
2
2
  return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(r);
3
3
  }
4
- function E(r, e) {
5
- return b(e) ? e : e ? r.replace(/\/?\/$/, "") + "/" + e.replace(/^\/+/, "") : r;
4
+ function b(r, e) {
5
+ return I(e) ? e : e ? r.replace(/\/?\/$/, "") + "/" + e.replace(/^\/+/, "") : r;
6
6
  }
7
- class w {
7
+ class g {
8
8
  /**
9
9
  * Creates a UrlBuilder instance
10
10
  *
@@ -37,13 +37,13 @@ class w {
37
37
  * ```
38
38
  */
39
39
  build(e, t) {
40
- const s = t?.path, o = t?.query, i = E(this.baseURL, e);
41
- let n = this.interpolateUrl(i, s);
42
- if (o) {
43
- const c = new URLSearchParams(o).toString();
44
- c && (n += "?" + c);
40
+ const s = t?.path, n = t?.query, i = b(this.baseURL, e);
41
+ let o = this.interpolateUrl(i, s);
42
+ if (n) {
43
+ const u = new URLSearchParams(n).toString();
44
+ u && (o += "?" + u);
45
45
  }
46
- return n;
46
+ return o;
47
47
  }
48
48
  /**
49
49
  * Resolves a complete URL from a FetchRequest
@@ -85,15 +85,15 @@ class w {
85
85
  * ```
86
86
  */
87
87
  interpolateUrl(e, t) {
88
- return t ? e.replace(/{([^}]+)}/g, (s, o) => {
89
- const i = t[o];
88
+ return t ? e.replace(/{([^}]+)}/g, (s, n) => {
89
+ const i = t[n];
90
90
  if (i === void 0)
91
- throw new Error(`Missing required path parameter: ${o}`);
91
+ throw new Error(`Missing required path parameter: ${n}`);
92
92
  return String(i);
93
93
  }) : e;
94
94
  }
95
95
  }
96
- function P(r, e) {
96
+ function w(r, e) {
97
97
  return typeof r < "u" ? r : e;
98
98
  }
99
99
  class p extends Error {
@@ -107,35 +107,35 @@ class p extends Error {
107
107
  super(s), this.name = "FetchTimeoutError", this.request = e, Object.setPrototypeOf(this, p.prototype);
108
108
  }
109
109
  }
110
- async function R(r) {
110
+ async function P(r) {
111
111
  const e = r.url, t = r.timeout, s = r;
112
112
  if (!t)
113
113
  return fetch(e, s);
114
- const o = new AbortController(), i = {
114
+ const n = new AbortController(), i = {
115
115
  ...s,
116
- signal: o.signal
116
+ signal: n.signal
117
117
  };
118
- let n = null;
119
- const c = new Promise((_, I) => {
120
- n = setTimeout(() => {
121
- n && clearTimeout(n);
122
- const f = new p(r);
123
- o.abort(f), I(f);
118
+ let o = null;
119
+ const u = new Promise((L, E) => {
120
+ o = setTimeout(() => {
121
+ o && clearTimeout(o);
122
+ const y = new p(r);
123
+ n.abort(y), E(y);
124
124
  }, t);
125
125
  });
126
126
  try {
127
- return await Promise.race([fetch(e, i), c]);
127
+ return await Promise.race([fetch(e, i), u]);
128
128
  } finally {
129
- n && clearTimeout(n);
129
+ o && clearTimeout(o);
130
130
  }
131
131
  }
132
132
  function a(r, e) {
133
133
  return e ? r.filter(e).sort((t, s) => t.order - s.order) : [...r].sort((t, s) => t.order - s.order);
134
134
  }
135
- var u = /* @__PURE__ */ ((r) => (r.GET = "GET", r.POST = "POST", r.PUT = "PUT", r.DELETE = "DELETE", r.PATCH = "PATCH", r.HEAD = "HEAD", r.OPTIONS = "OPTIONS", r))(u || {});
135
+ 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 || {});
136
136
  const v = "Content-Type";
137
- var y = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(y || {});
138
- class A {
137
+ var f = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(f || {});
138
+ class R {
139
139
  constructor() {
140
140
  this.name = "RequestBodyInterceptor", this.order = Number.MIN_SAFE_INTEGER + 200;
141
141
  }
@@ -179,11 +179,11 @@ class A {
179
179
  const t = e.request;
180
180
  if (t.body === void 0 || t.body === null || typeof t.body != "object" || t.body instanceof ArrayBuffer || ArrayBuffer.isView(t.body) || // Includes TypedArray and DataView
181
181
  t.body instanceof Blob || t.body instanceof File || t.body instanceof URLSearchParams || t.body instanceof FormData || t.body instanceof ReadableStream)
182
- return e;
182
+ return;
183
183
  const s = { ...t };
184
184
  s.body = JSON.stringify(t.body), s.headers || (s.headers = {});
185
- const o = s.headers;
186
- return o["Content-Type"] || (o["Content-Type"] = y.APPLICATION_JSON), e.request = s, e;
185
+ const n = s.headers;
186
+ n["Content-Type"] || (n["Content-Type"] = f.APPLICATION_JSON), e.request = s;
187
187
  }
188
188
  }
189
189
  class F {
@@ -198,7 +198,6 @@ class F {
198
198
  * function to send the network request.
199
199
  *
200
200
  * @param exchange - Exchange object containing request information
201
- * @returns Promise<FetchExchange> Processed exchange object containing response information
202
201
  *
203
202
  * @throws {FetchTimeoutError} Throws timeout exception when request times out
204
203
  *
@@ -215,10 +214,10 @@ class F {
215
214
  * console.log(result.response); // HTTP response object
216
215
  */
217
216
  async intercept(e) {
218
- return e.response = await R(e.request), e;
217
+ e.response = await P(e.request);
219
218
  }
220
219
  }
221
- class g {
220
+ class A {
222
221
  constructor() {
223
222
  this.name = "UrlResolveInterceptor", this.order = Number.MIN_SAFE_INTEGER + 100;
224
223
  }
@@ -230,7 +229,7 @@ class g {
230
229
  */
231
230
  intercept(e) {
232
231
  const t = e.request;
233
- return t.url = e.fetcher.urlBuilder.resolveRequestUrl(t), e;
232
+ t.url = e.fetcher.urlBuilder.resolveRequestUrl(t);
234
233
  }
235
234
  }
236
235
  class h {
@@ -316,39 +315,58 @@ class h {
316
315
  * is propagated to the caller.
317
316
  */
318
317
  async intercept(e) {
319
- let t = e;
320
- for (const s of this.sortedInterceptors)
321
- t = await s.intercept(t);
322
- return t;
318
+ for (const t of this.sortedInterceptors)
319
+ await t.intercept(e);
323
320
  }
324
321
  }
325
322
  class N {
326
323
  constructor() {
327
324
  this.request = new h([
328
- new g(),
329
325
  new A(),
326
+ new R(),
330
327
  new F()
331
328
  ]), this.response = new h(), this.error = new h();
332
329
  }
333
330
  }
331
+ class S {
332
+ constructor(e, t, s, n) {
333
+ this.attributes = {}, this.fetcher = e, this.request = t, this.response = s, this.error = n;
334
+ }
335
+ /**
336
+ * Checks if the exchange has an error
337
+ *
338
+ * @returns true if an error is present, false otherwise
339
+ */
340
+ hasError() {
341
+ return !!this.error;
342
+ }
343
+ /**
344
+ * Checks if the exchange has a response
345
+ *
346
+ * @returns true if a response is present, false otherwise
347
+ */
348
+ hasResponse() {
349
+ return !!this.response;
350
+ }
351
+ }
334
352
  function d(r, e) {
335
353
  if (!(r === void 0 && e === void 0))
336
354
  return e === void 0 ? r : r === void 0 ? e : { ...r, ...e };
337
355
  }
338
356
  const l = {
339
- "Content-Type": y.APPLICATION_JSON
357
+ "Content-Type": f.APPLICATION_JSON
340
358
  }, T = {
341
359
  baseURL: "",
342
360
  headers: l
343
361
  };
344
- class S {
362
+ class q {
345
363
  /**
346
364
  * Create a Fetcher instance
347
365
  *
348
366
  * @param options - Fetcher configuration options
349
367
  */
350
368
  constructor(e = T) {
351
- this.headers = l, this.urlBuilder = new w(e.baseURL), this.headers = e.headers ?? l, this.timeout = e.timeout, this.interceptors = e.interceptors ?? new N();
369
+ this.headers = l, this.urlBuilder = new g(e.baseURL), this.headers = e.headers ?? l, this.timeout = e.timeout, this.interceptors = e.interceptors ?? new N();
352
370
  }
353
371
  /**
354
372
  * Make an HTTP request
@@ -360,10 +378,10 @@ class S {
360
378
  async fetch(e, t = {}) {
361
379
  const s = t;
362
380
  s.url = e;
363
- const o = await this.request(s);
364
- if (!o.response)
381
+ const n = await this.request(s);
382
+ if (!n.response)
365
383
  throw new Error(`Request to ${s.url} failed with no response`);
366
- return o.response;
384
+ return n.response;
367
385
  }
368
386
  /**
369
387
  * Send an HTTP request
@@ -377,15 +395,9 @@ class S {
377
395
  const t = d(e.headers, this.headers), s = {
378
396
  ...e,
379
397
  headers: t,
380
- timeout: P(e.timeout, this.timeout)
381
- }, o = {
382
- fetcher: this,
383
- request: s,
384
- response: void 0,
385
- error: void 0,
386
- attributes: {}
387
- };
388
- return this.exchange(o);
398
+ timeout: w(e.timeout, this.timeout)
399
+ }, n = new S(this, s);
400
+ return this.exchange(n);
389
401
  }
390
402
  /**
391
403
  * Process a fetch exchange through the interceptor chain
@@ -405,9 +417,9 @@ class S {
405
417
  */
406
418
  async exchange(e) {
407
419
  try {
408
- return e = await this.interceptors.request.intercept(e), e = await this.interceptors.response.intercept(e), e;
420
+ return await this.interceptors.request.intercept(e), await this.interceptors.response.intercept(e), e;
409
421
  } catch (t) {
410
- if (e.error = t, e = await this.interceptors.error.intercept(e), e.response)
422
+ if (e.error = t, await this.interceptors.error.intercept(e), e.hasResponse())
411
423
  return e;
412
424
  throw e.error;
413
425
  }
@@ -434,7 +446,7 @@ class S {
434
446
  * @returns Promise<Response> HTTP response
435
447
  */
436
448
  async get(e, t = {}) {
437
- return this.methodFetch(u.GET, e, t);
449
+ return this.methodFetch(c.GET, e, t);
438
450
  }
439
451
  /**
440
452
  * Make a POST request
@@ -444,7 +456,7 @@ class S {
444
456
  * @returns Promise<Response> HTTP response
445
457
  */
446
458
  async post(e, t = {}) {
447
- return this.methodFetch(u.POST, e, t);
459
+ return this.methodFetch(c.POST, e, t);
448
460
  }
449
461
  /**
450
462
  * Make a PUT request
@@ -454,7 +466,7 @@ class S {
454
466
  * @returns Promise<Response> HTTP response
455
467
  */
456
468
  async put(e, t = {}) {
457
- return this.methodFetch(u.PUT, e, t);
469
+ return this.methodFetch(c.PUT, e, t);
458
470
  }
459
471
  /**
460
472
  * Make a DELETE request
@@ -464,7 +476,7 @@ class S {
464
476
  * @returns Promise<Response> HTTP response
465
477
  */
466
478
  async delete(e, t = {}) {
467
- return this.methodFetch(u.DELETE, e, t);
479
+ return this.methodFetch(c.DELETE, e, t);
468
480
  }
469
481
  /**
470
482
  * Make a PATCH request
@@ -474,7 +486,7 @@ class S {
474
486
  * @returns Promise<Response> HTTP response
475
487
  */
476
488
  async patch(e, t = {}) {
477
- return this.methodFetch(u.PATCH, e, t);
489
+ return this.methodFetch(c.PATCH, e, t);
478
490
  }
479
491
  /**
480
492
  * Make a HEAD request
@@ -484,7 +496,7 @@ class S {
484
496
  * @returns Promise<Response> HTTP response
485
497
  */
486
498
  async head(e, t = {}) {
487
- return this.methodFetch(u.HEAD, e, t);
499
+ return this.methodFetch(c.HEAD, e, t);
488
500
  }
489
501
  /**
490
502
  * Make an OPTIONS request
@@ -494,11 +506,11 @@ class S {
494
506
  * @returns Promise<Response> HTTP response
495
507
  */
496
508
  async options(e, t = {}) {
497
- return this.methodFetch(u.OPTIONS, e, t);
509
+ return this.methodFetch(c.OPTIONS, e, t);
498
510
  }
499
511
  }
500
512
  const m = "default";
501
- class q {
513
+ class O {
502
514
  constructor() {
503
515
  this.registrar = /* @__PURE__ */ new Map();
504
516
  }
@@ -598,8 +610,8 @@ class q {
598
610
  return new Map(this.registrar);
599
611
  }
600
612
  }
601
- const O = new q();
602
- function L(r, e) {
613
+ const U = new O();
614
+ function C(r, e) {
603
615
  if (Object.keys(r).length === 0)
604
616
  return e;
605
617
  if (Object.keys(e).length === 0)
@@ -610,19 +622,19 @@ function L(r, e) {
610
622
  }, s = {
611
623
  ...r.headers,
612
624
  ...e.headers
613
- }, o = e.method ?? r.method, i = e.body ?? r.body, n = e.timeout ?? r.timeout, c = e.signal ?? r.signal;
625
+ }, n = e.method ?? r.method, i = e.body ?? r.body, o = e.timeout ?? r.timeout, u = e.signal ?? r.signal;
614
626
  return {
615
627
  ...r,
616
628
  ...e,
617
- method: o,
629
+ method: n,
618
630
  urlParams: t,
619
631
  headers: s,
620
632
  body: i,
621
- timeout: n,
622
- signal: c
633
+ timeout: o,
634
+ signal: u
623
635
  };
624
636
  }
625
- class U extends S {
637
+ class _ extends q {
626
638
  /**
627
639
  * Create a NamedFetcher instance and automatically register it with the global fetcherRegistrar
628
640
  *
@@ -641,33 +653,34 @@ class U extends S {
641
653
  * });
642
654
  */
643
655
  constructor(e, t = T) {
644
- super(t), this.name = e, O.register(e, this);
656
+ super(t), this.name = e, U.register(e, this);
645
657
  }
646
658
  }
647
- const C = new U(m);
659
+ const D = new _(m);
648
660
  export {
649
661
  v as ContentTypeHeader,
650
- y as ContentTypeValues,
662
+ f as ContentTypeValues,
651
663
  m as DEFAULT_FETCHER_NAME,
652
664
  T as DEFAULT_OPTIONS,
665
+ S as FetchExchange,
653
666
  F as FetchInterceptor,
654
667
  p as FetchTimeoutError,
655
- S as Fetcher,
668
+ q as Fetcher,
656
669
  N as FetcherInterceptors,
657
- q as FetcherRegistrar,
658
- u as HttpMethod,
670
+ O as FetcherRegistrar,
671
+ c as HttpMethod,
659
672
  h as InterceptorManager,
660
- U as NamedFetcher,
661
- A as RequestBodyInterceptor,
662
- w as UrlBuilder,
663
- g as UrlResolveInterceptor,
664
- E as combineURLs,
665
- C as fetcher,
666
- O as fetcherRegistrar,
667
- b as isAbsoluteURL,
673
+ _ as NamedFetcher,
674
+ R as RequestBodyInterceptor,
675
+ g as UrlBuilder,
676
+ A as UrlResolveInterceptor,
677
+ b as combineURLs,
678
+ D as fetcher,
679
+ U as fetcherRegistrar,
680
+ I as isAbsoluteURL,
668
681
  d as mergeRecords,
669
- L as mergeRequest,
670
- P as resolveTimeout,
671
- R as timeoutFetch,
682
+ C as mergeRequest,
683
+ w as resolveTimeout,
684
+ P as timeoutFetch,
672
685
  a as toSorted
673
686
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(n,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(n=typeof globalThis<"u"?globalThis:n||self,a(n.Fetcher={}))})(this,(function(n){"use strict";function a(r){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(r)}function E(r,e){return a(e)?e:e?r.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):r}class b{constructor(e){this.baseURL=e}build(e,t){const s=t?.path,o=t?.query,c=E(this.baseURL,e);let i=this.interpolateUrl(c,s);if(o){const h=new URLSearchParams(o).toString();h&&(i+="?"+h)}return i}resolveRequestUrl(e){return this.build(e.url,e.urlParams)}interpolateUrl(e,t){return t?e.replace(/{([^}]+)}/g,(s,o)=>{const c=t[o];if(c===void 0)throw new Error(`Missing required path parameter: ${o}`);return String(c)}):e}}function F(r,e){return typeof r<"u"?r:e}class d extends Error{constructor(e){const t=e.method||"GET",s=`Request timeout of ${e.timeout}ms exceeded for ${t} ${e.url}`;super(s),this.name="FetchTimeoutError",this.request=e,Object.setPrototypeOf(this,d.prototype)}}async function R(r){const e=r.url,t=r.timeout,s=r;if(!t)return fetch(e,s);const o=new AbortController,c={...s,signal:o.signal};let i=null;const h=new Promise((D,C)=>{i=setTimeout(()=>{i&&clearTimeout(i);const U=new d(r);o.abort(U),C(U)},t)});try{return await Promise.race([fetch(e,c),h])}finally{i&&clearTimeout(i)}}function l(r,e){return e?r.filter(e).sort((t,s)=>t.order-s.order):[...r].sort((t,s)=>t.order-s.order)}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||{});const _="Content-Type";var m=(r=>(r.APPLICATION_JSON="application/json",r.TEXT_EVENT_STREAM="text/event-stream",r))(m||{});class g{constructor(){this.name="RequestBodyInterceptor",this.order=Number.MIN_SAFE_INTEGER+200}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 o=s.headers;return o["Content-Type"]||(o["Content-Type"]=m.APPLICATION_JSON),e.request=s,e}}class P{constructor(){this.name="FetchInterceptor",this.order=Number.MAX_SAFE_INTEGER-100}async intercept(e){return e.response=await R(e.request),e}}class w{constructor(){this.name="UrlResolveInterceptor",this.order=Number.MIN_SAFE_INTEGER+100}intercept(e){const t=e.request;return t.url=e.fetcher.urlBuilder.resolveRequestUrl(t),e}}class f{constructor(e=[]){this.sortedInterceptors=[],this.sortedInterceptors=l(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=l([...this.sortedInterceptors,e]),!0)}eject(e){const t=this.sortedInterceptors;return this.sortedInterceptors=l(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 A{constructor(){this.request=new f([new w,new g,new P]),this.response=new f,this.error=new f}}function y(r,e){if(!(r===void 0&&e===void 0))return e===void 0?r:r===void 0?e:{...r,...e}}const p={"Content-Type":m.APPLICATION_JSON},I={baseURL:"",headers:p};class N{constructor(e=I){this.headers=p,this.urlBuilder=new b(e.baseURL),this.headers=e.headers??p,this.timeout=e.timeout,this.interceptors=e.interceptors??new A}async fetch(e,t={}){const s=t;s.url=e;const o=await this.request(s);if(!o.response)throw new Error(`Request to ${s.url} failed with no response`);return o.response}async request(e){const t=y(e.headers,this.headers),s={...e,headers:t,timeout:F(e.timeout,this.timeout)},o={fetcher:this,request:s,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(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)}}const T="default";class S{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(T)}set default(e){this.register(T,e)}get fetchers(){return new Map(this.registrar)}}const q=new S;function v(r,e){if(Object.keys(r).length===0)return e;if(Object.keys(e).length===0)return r;const t={path:y(r.urlParams?.path,e.urlParams?.path),query:y(r.urlParams?.query,e.urlParams?.query)},s={...r.headers,...e.headers},o=e.method??r.method,c=e.body??r.body,i=e.timeout??r.timeout,h=e.signal??r.signal;return{...r,...e,method:o,urlParams:t,headers:s,body:c,timeout:i,signal:h}}class O extends N{constructor(e,t=I){super(t),this.name=e,q.register(e,this)}}const L=new O(T);n.ContentTypeHeader=_,n.ContentTypeValues=m,n.DEFAULT_FETCHER_NAME=T,n.DEFAULT_OPTIONS=I,n.FetchInterceptor=P,n.FetchTimeoutError=d,n.Fetcher=N,n.FetcherInterceptors=A,n.FetcherRegistrar=S,n.HttpMethod=u,n.InterceptorManager=f,n.NamedFetcher=O,n.RequestBodyInterceptor=g,n.UrlBuilder=b,n.UrlResolveInterceptor=w,n.combineURLs=E,n.fetcher=L,n.fetcherRegistrar=q,n.isAbsoluteURL=a,n.mergeRecords=y,n.mergeRequest=v,n.resolveTimeout=F,n.timeoutFetch=R,n.toSorted=l,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(n,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(n=typeof globalThis<"u"?globalThis:n||self,a(n.Fetcher={}))})(this,(function(n){"use strict";function a(r){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(r)}function g(r,e){return a(e)?e:e?r.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):r}class I{constructor(e){this.baseURL=e}build(e,t){const s=t?.path,o=t?.query,u=g(this.baseURL,e);let i=this.interpolateUrl(u,s);if(o){const h=new URLSearchParams(o).toString();h&&(i+="?"+h)}return i}resolveRequestUrl(e){return this.build(e.url,e.urlParams)}interpolateUrl(e,t){return t?e.replace(/{([^}]+)}/g,(s,o)=>{const u=t[o];if(u===void 0)throw new Error(`Missing required path parameter: ${o}`);return String(u)}):e}}function b(r,e){return typeof r<"u"?r:e}class d extends Error{constructor(e){const t=e.method||"GET",s=`Request timeout of ${e.timeout}ms exceeded for ${t} ${e.url}`;super(s),this.name="FetchTimeoutError",this.request=e,Object.setPrototypeOf(this,d.prototype)}}async function F(r){const e=r.url,t=r.timeout,s=r;if(!t)return fetch(e,s);const o=new AbortController,u={...s,signal:o.signal};let i=null;const h=new Promise((B,D)=>{i=setTimeout(()=>{i&&clearTimeout(i);const _=new d(r);o.abort(_),D(_)},t)});try{return await Promise.race([fetch(e,u),h])}finally{i&&clearTimeout(i)}}function l(r,e){return e?r.filter(e).sort((t,s)=>t.order-s.order):[...r].sort((t,s)=>t.order-s.order)}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||{});const L="Content-Type";var m=(r=>(r.APPLICATION_JSON="application/json",r.TEXT_EVENT_STREAM="text/event-stream",r))(m||{});class R{constructor(){this.name="RequestBodyInterceptor",this.order=Number.MIN_SAFE_INTEGER+200}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;const s={...t};s.body=JSON.stringify(t.body),s.headers||(s.headers={});const o=s.headers;o["Content-Type"]||(o["Content-Type"]=m.APPLICATION_JSON),e.request=s}}class w{constructor(){this.name="FetchInterceptor",this.order=Number.MAX_SAFE_INTEGER-100}async intercept(e){e.response=await F(e.request)}}class P{constructor(){this.name="UrlResolveInterceptor",this.order=Number.MIN_SAFE_INTEGER+100}intercept(e){const t=e.request;t.url=e.fetcher.urlBuilder.resolveRequestUrl(t)}}class f{constructor(e=[]){this.sortedInterceptors=[],this.sortedInterceptors=l(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=l([...this.sortedInterceptors,e]),!0)}eject(e){const t=this.sortedInterceptors;return this.sortedInterceptors=l(t,s=>s.name!==e),t.length!==this.sortedInterceptors.length}clear(){this.sortedInterceptors=[]}async intercept(e){for(const t of this.sortedInterceptors)await t.intercept(e)}}class A{constructor(){this.request=new f([new P,new R,new w]),this.response=new f,this.error=new f}}class N{constructor(e,t,s,o){this.attributes={},this.fetcher=e,this.request=t,this.response=s,this.error=o}hasError(){return!!this.error}hasResponse(){return!!this.response}}function y(r,e){if(!(r===void 0&&e===void 0))return e===void 0?r:r===void 0?e:{...r,...e}}const p={"Content-Type":m.APPLICATION_JSON},E={baseURL:"",headers:p};class S{constructor(e=E){this.headers=p,this.urlBuilder=new I(e.baseURL),this.headers=e.headers??p,this.timeout=e.timeout,this.interceptors=e.interceptors??new A}async fetch(e,t={}){const s=t;s.url=e;const o=await this.request(s);if(!o.response)throw new Error(`Request to ${s.url} failed with no response`);return o.response}async request(e){const t=y(e.headers,this.headers),s={...e,headers:t,timeout:b(e.timeout,this.timeout)},o=new N(this,s);return this.exchange(o)}async exchange(e){try{return await this.interceptors.request.intercept(e),await this.interceptors.response.intercept(e),e}catch(t){if(e.error=t,await this.interceptors.error.intercept(e),e.hasResponse())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 T="default";class q{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(T)}set default(e){this.register(T,e)}get fetchers(){return new Map(this.registrar)}}const O=new q;function v(r,e){if(Object.keys(r).length===0)return e;if(Object.keys(e).length===0)return r;const t={path:y(r.urlParams?.path,e.urlParams?.path),query:y(r.urlParams?.query,e.urlParams?.query)},s={...r.headers,...e.headers},o=e.method??r.method,u=e.body??r.body,i=e.timeout??r.timeout,h=e.signal??r.signal;return{...r,...e,method:o,urlParams:t,headers:s,body:u,timeout:i,signal:h}}class U extends S{constructor(e,t=E){super(t),this.name=e,O.register(e,this)}}const C=new U(T);n.ContentTypeHeader=L,n.ContentTypeValues=m,n.DEFAULT_FETCHER_NAME=T,n.DEFAULT_OPTIONS=E,n.FetchExchange=N,n.FetchInterceptor=w,n.FetchTimeoutError=d,n.Fetcher=S,n.FetcherInterceptors=A,n.FetcherRegistrar=q,n.HttpMethod=c,n.InterceptorManager=f,n.NamedFetcher=U,n.RequestBodyInterceptor=R,n.UrlBuilder=I,n.UrlResolveInterceptor=P,n.combineURLs=g,n.fetcher=C,n.fetcherRegistrar=O,n.isAbsoluteURL=a,n.mergeRecords=y,n.mergeRequest=v,n.resolveTimeout=b,n.timeoutFetch=F,n.toSorted=l,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
@@ -13,14 +13,15 @@ import { FetchExchange } from './fetchExchange';
13
13
  *
14
14
  * @example
15
15
  * // Example of a custom request interceptor
16
- * const loggingInterceptor: Interceptor = {
17
- * name: 'LoggingInterceptor',
18
- * order: 0,
19
- * async intercept(exchange: FetchExchange): Promise<FetchExchange> {
20
- * console.log(`Making request to ${exchange.url}`);
21
- * const result = await next.intercept(exchange);
22
- * console.log(`Received response with status ${result.response?.status}`);
23
- * return result;
16
+ * const customRequestInterceptor: Interceptor = {
17
+ * name: 'CustomRequestInterceptor',
18
+ * order: 100,
19
+ * async intercept(exchange: FetchExchange): Promise<void> {
20
+ * // Modify request headers
21
+ * exchange.request.headers = {
22
+ * ...exchange.request.headers,
23
+ * 'X-Custom-Header': 'custom-value'
24
+ * };
24
25
  * }
25
26
  * };
26
27
  */
@@ -38,16 +39,15 @@ export interface Interceptor extends NamedCapable, OrderedCapable {
38
39
  *
39
40
  * This method is called by the InterceptorManager to process the exchange object.
40
41
  * The interceptor can modify the request, response, or error properties of the
41
- * exchange object and then pass it to the next interceptor in the chain.
42
+ * exchange object directly.
42
43
  *
43
44
  * @param exchange - The data to be processed, containing request, response, and error information
44
- * @returns The processed data, which can be returned synchronously or asynchronously
45
45
  *
46
46
  * @remarks
47
- * Interceptors should either return the exchange object (possibly modified) or
48
- * a new exchange object. They can also throw errors or transform errors into responses.
47
+ * Interceptors should modify the exchange object directly rather than returning it.
48
+ * They can also throw errors or transform errors into responses.
49
49
  */
50
- intercept(exchange: FetchExchange): FetchExchange | Promise<FetchExchange>;
50
+ intercept(exchange: FetchExchange): void | Promise<void>;
51
51
  }
52
52
  /**
53
53
  * InterceptorManager Class
@@ -140,7 +140,7 @@ export declare class InterceptorManager implements Interceptor {
140
140
  * If any interceptor throws an error, the execution chain is broken and the error
141
141
  * is propagated to the caller.
142
142
  */
143
- intercept(exchange: FetchExchange): Promise<FetchExchange>;
143
+ intercept(exchange: FetchExchange): Promise<void>;
144
144
  }
145
145
  /**
146
146
  * FetcherInterceptors Class
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,cAAc,EAAY,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,WAAY,SAAQ,YAAY,EAAE,cAAc;IAC/D;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC5E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAqB;IAE/C;;;;;;;;OAQG;gBACS,YAAY,GAAE,WAAW,EAAO;IAI5C;;;;;;;;;;;;OAYG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO;IAWtC;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAQjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,mBAAmB;IAC9B;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE,kBAAkB,CAIxB;IAEH;;;;;;;;OAQG;IACH,QAAQ,EAAE,kBAAkB,CAA4B;IAExD;;;;;;;;;OASG;IACH,KAAK,EAAE,kBAAkB,CAA4B;CACtD"}
1
+ {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,cAAc,EAAY,MAAM,kBAAkB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,WAAY,SAAQ,YAAY,EAAE,cAAc;IAC/D;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD;;;;OAIG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAqB;IAE/C;;;;;;;;OAQG;gBACS,YAAY,GAAE,WAAW,EAAO;IAI5C;;;;;;;;;;;;OAYG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO;IAWtC;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,mBAAmB;IAC9B;;;;;;;;;;;;OAYG;IACH,OAAO,EAAE,kBAAkB,CAIxB;IAEH;;;;;;;;OAQG;IACH,QAAQ,EAAE,kBAAkB,CAA4B;IAExD;;;;;;;;;OASG;IACH,KAAK,EAAE,kBAAkB,CAA4B;CACtD"}
@@ -64,6 +64,6 @@ export declare class RequestBodyInterceptor implements Interceptor {
64
64
  * // result.request.body will be '{"name":"John","age":30}'
65
65
  * // result.request.headers will include 'Content-Type: application/json'
66
66
  */
67
- intercept(exchange: FetchExchange): FetchExchange;
67
+ intercept(exchange: FetchExchange): void;
68
68
  }
69
69
  //# sourceMappingURL=requestBodyInterceptor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"requestBodyInterceptor.d.ts","sourceRoot":"","sources":["../src/requestBodyInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IACxD;;OAEG;IACH,IAAI,SAA4B;IAEhC;;;;;;;;;OASG;IACH,KAAK,SAAiC;IAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa;CA2ClD"}
1
+ {"version":3,"file":"requestBodyInterceptor.d.ts","sourceRoot":"","sources":["../src/requestBodyInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IACxD;;OAEG;IACH,IAAI,SAA4B;IAEhC;;;;;;;;;OASG;IACH,KAAK,SAAiC;IAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa;CA0ClC"}
package/dist/timeout.d.ts CHANGED
@@ -62,7 +62,6 @@ export declare class FetchTimeoutError extends Error {
62
62
  * it returns the result or throws an exception.
63
63
  *
64
64
  * @param request - The request initialization options
65
- * @param timeout - Optional timeout in milliseconds
66
65
  * @returns Promise<Response> HTTP response Promise
67
66
  * @throws FetchTimeoutError Thrown when the request times out
68
67
  *
@@ -1 +1 @@
1
- {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,cAAc,CAAC,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;;;OAIG;gBACS,OAAO,EAAE,YAAY;CASlC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyC3E"}
1
+ {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../src/timeout.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,cAAc,CAAC,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;;;OAIG;gBACS,OAAO,EAAE,YAAY;CASlC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyC3E"}
@@ -40,6 +40,6 @@ export declare class UrlResolveInterceptor implements Interceptor {
40
40
  * @param exchange - The fetch exchange containing the request information
41
41
  * @returns The modified exchange with the resolved URL
42
42
  */
43
- intercept(exchange: FetchExchange): FetchExchange;
43
+ intercept(exchange: FetchExchange): void;
44
44
  }
45
45
  //# sourceMappingURL=urlResolveInterceptor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"urlResolveInterceptor.d.ts","sourceRoot":"","sources":["../src/urlResolveInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,qBAAsB,YAAW,WAAW;IACvD;;OAEG;IACH,IAAI,SAA2B;IAE/B;;;;;;;;OAQG;IACH,KAAK,SAAiC;IAEtC;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,aAAa;CAKlD"}
1
+ {"version":3,"file":"urlResolveInterceptor.d.ts","sourceRoot":"","sources":["../src/urlResolveInterceptor.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,qBAAsB,YAAW,WAAW;IACvD;;OAEG;IACH,IAAI,SAA2B;IAE/B;;;;;;;;OAQG;IACH,KAAK,SAAiC;IAEtC;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa;CAIlC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher",
3
- "version": "0.8.8",
3
+ "version": "0.9.0",
4
4
  "description": "Ultra-lightweight (1.9kB) HTTP client with built-in path parameters and Axios-like API",
5
5
  "keywords": [
6
6
  "fetch",