@ahoo-wang/fetcher 0.11.2 → 1.0.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
@@ -8,7 +8,7 @@
8
8
  [![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40ahoo-wang%2Ffetcher)](https://www.npmjs.com/package/@ahoo-wang/fetcher)
9
9
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Ahoo-Wang/fetcher)
10
10
 
11
- A modern, ultra-lightweight HTTP client with built-in path parameters, query parameters, and Axios-like API.
11
+ The lightweight core that powers the entire Fetcher ecosystem. Ultra-lightweight foundation with Axios-like API.
12
12
 
13
13
  ## 🌟 Features
14
14
 
@@ -63,6 +63,24 @@ const createUserResponse = await fetcher.post('/users', {
63
63
  });
64
64
  ```
65
65
 
66
+ ### Integration Test Example: Typicode API Integration
67
+
68
+ The following example shows how to integrate with the JSONPlaceholder API, similar to the integration test in the
69
+ Fetcher project. You can find the complete implementation
70
+ in [integration-test/src/fetcher/typicodeFetcher.ts](../../integration-test/src/fetcher/typicodeFetcher.ts).
71
+
72
+ ```typescript
73
+ import { NamedFetcher } from '@ahoo-wang/fetcher';
74
+ import { cosecRequestInterceptor, cosecResponseInterceptor } from '../cosec';
75
+
76
+ export const typicodeFetcher = new NamedFetcher('typicode', {
77
+ baseURL: 'https://jsonplaceholder.typicode.com',
78
+ });
79
+
80
+ typicodeFetcher.interceptors.request.use(cosecRequestInterceptor);
81
+ typicodeFetcher.interceptors.response.use(cosecResponseInterceptor);
82
+ ```
83
+
66
84
  ### Named Fetcher Usage
67
85
 
68
86
  ```typescript
package/README.zh-CN.md CHANGED
@@ -63,6 +63,24 @@ const createUserResponse = await fetcher.post('/users', {
63
63
  });
64
64
  ```
65
65
 
66
+ ### 集成测试示例:Typicode API 集成
67
+
68
+ 以下示例展示了如何与 JSONPlaceholder API 集成,类似于 Fetcher
69
+ 项目中的集成测试。您可以在 [integration-test/src/fetcher/typicodeFetcher.ts](../../integration-test/src/fetcher/typicodeFetcher.ts)
70
+ 中找到完整实现。
71
+
72
+ ```typescript
73
+ import { NamedFetcher } from '@ahoo-wang/fetcher';
74
+ import { cosecRequestInterceptor, cosecResponseInterceptor } from '../cosec';
75
+
76
+ export const typicodeFetcher = new NamedFetcher('typicode', {
77
+ baseURL: 'https://jsonplaceholder.typicode.com',
78
+ });
79
+
80
+ typicodeFetcher.interceptors.request.use(cosecRequestInterceptor);
81
+ typicodeFetcher.interceptors.response.use(cosecResponseInterceptor);
82
+ ```
83
+
66
84
  ### 命名 Fetcher 用法
67
85
 
68
86
  ```typescript
@@ -95,16 +113,6 @@ try {
95
113
  }
96
114
  ```
97
115
 
98
- ### 默认 Fetcher 用法
99
-
100
- ```typescript
101
- import { fetcher } from '@ahoo-wang/fetcher';
102
-
103
- // 直接使用默认 fetcher
104
- const response = await fetcher.get('/users');
105
- const data = await response.json<User>();
106
- ```
107
-
108
116
  ## 🔗 拦截器系统
109
117
 
110
118
  ### 核心概念
@@ -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,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,cAAc,EAEd,YAAY,EACZ,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,qBAAqB,EACrB,cAAc;IAChB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,OACX,YAAW,iBAAiB,EAAE,qBAAqB,EAAE,cAAc;IACnE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAmB;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAE1C;;;;;;;OAOG;gBACS,OAAO,GAAE,cAAgC;IAOrD;;;;;;;;;;OAUG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAO3E;;;;;;;;;;OAUG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAa5D;;;;;;;;;;OAUG;YACW,WAAW;IAWzB;;;;;;;;;OASG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;;OASG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;;OASG;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,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,cAAc,EAEd,YAAY,EACZ,gBAAgB,EAEhB,cAAc,EACd,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cACf,SAAQ,cAAc,EACpB,qBAAqB,EACrB,cAAc;IAChB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,OACX,YAAW,iBAAiB,EAAE,qBAAqB,EAAE,cAAc;IACnE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAmB;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAE1C;;;;;;;OAOG;gBACS,OAAO,GAAE,cAAgC;IAOrD;;;;;;;;;;OAUG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAO3E;;;;;;;;;;OAUG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAgB5D;;;;;;;;;;OAUG;YACW,WAAW;IAWzB;;;;;;;;;OASG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,GAAG,CACP,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,MAAM,CACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;OAQG;IACG,KAAK,CACT,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAC7C,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;;OASG;IACG,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,MAAM,CAAM,GACtD,OAAO,CAAC,QAAQ,CAAC;IAIpB;;;;;;;;;OASG;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
@@ -105,7 +105,7 @@ class a extends Error {
105
105
  super(s), this.cause = t, this.name = "FetcherError", t?.stack && (this.stack = t.stack), Object.setPrototypeOf(this, a.prototype);
106
106
  }
107
107
  }
108
- class T extends a {
108
+ class m extends a {
109
109
  /**
110
110
  * Creates a new FetchTimeoutError instance.
111
111
  *
@@ -113,7 +113,7 @@ class T extends a {
113
113
  */
114
114
  constructor(e) {
115
115
  const t = e.method || "GET", s = `Request timeout of ${e.timeout}ms exceeded for ${t} ${e.url}`;
116
- super(s), this.name = "FetchTimeoutError", this.request = e, Object.setPrototypeOf(this, T.prototype);
116
+ super(s), this.name = "FetchTimeoutError", this.request = e, Object.setPrototypeOf(this, m.prototype);
117
117
  }
118
118
  }
119
119
  function S(r, e) {
@@ -131,8 +131,8 @@ async function _(r) {
131
131
  const u = new Promise((X, A) => {
132
132
  n = setTimeout(() => {
133
133
  n && clearTimeout(n);
134
- const y = new T(r);
135
- o.abort(y), A(y);
134
+ const f = new m(r);
135
+ o.abort(f), A(f);
136
136
  }, t);
137
137
  });
138
138
  try {
@@ -158,7 +158,7 @@ class N {
158
158
  }
159
159
  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 || {});
160
160
  const z = "Content-Type";
161
- var R = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(R || {});
161
+ var T = /* @__PURE__ */ ((r) => (r.APPLICATION_JSON = "application/json", r.TEXT_EVENT_STREAM = "text/event-stream", r))(T || {});
162
162
  const F = "RequestBodyInterceptor", q = I + 1e3;
163
163
  class U {
164
164
  constructor() {
@@ -209,7 +209,7 @@ class U {
209
209
  const s = { ...t };
210
210
  s.body = JSON.stringify(t.body), s.headers || (s.headers = {});
211
211
  const o = s.headers;
212
- o["Content-Type"] || (o["Content-Type"] = R.APPLICATION_JSON), e.request = s;
212
+ o["Content-Type"] || (o["Content-Type"] = T.APPLICATION_JSON), e.request = s;
213
213
  }
214
214
  }
215
215
  const C = "FetchInterceptor", L = Number.MAX_SAFE_INTEGER - 1e3;
@@ -342,11 +342,11 @@ class l {
342
342
  await t.intercept(e);
343
343
  }
344
344
  }
345
- class f extends a {
345
+ class R extends a {
346
346
  constructor(e) {
347
347
  super(
348
348
  `Request failed with status code ${e.response?.status} for ${e.request.url}`
349
- ), this.exchange = e, this.name = "HttpStatusValidationError", Object.setPrototypeOf(this, f.prototype);
349
+ ), this.exchange = e, this.name = "HttpStatusValidationError", Object.setPrototypeOf(this, R.prototype);
350
350
  }
351
351
  }
352
352
  const v = (r) => r >= 200 && r < 300, B = "ValidateStatusInterceptor", G = Number.MAX_SAFE_INTEGER - 1e3;
@@ -393,7 +393,7 @@ class M {
393
393
  return;
394
394
  const t = e.response.status;
395
395
  if (!this.validateStatus(t))
396
- throw new f(e);
396
+ throw new R(e);
397
397
  }
398
398
  }
399
399
  class h extends a {
@@ -553,15 +553,11 @@ class j {
553
553
  return this.response;
554
554
  }
555
555
  }
556
- function p(r, e) {
557
- if (!(r === void 0 && e === void 0))
558
- return e === void 0 ? r : r === void 0 ? e : { ...r, ...e };
559
- }
560
- const E = {
561
- "Content-Type": R.APPLICATION_JSON
556
+ const p = {
557
+ "Content-Type": T.APPLICATION_JSON
562
558
  }, O = {
563
559
  baseURL: "",
564
- headers: E
560
+ headers: p
565
561
  };
566
562
  class V {
567
563
  /**
@@ -573,7 +569,7 @@ class V {
573
569
  * @param options - Configuration options for the Fetcher instance
574
570
  */
575
571
  constructor(e = O) {
576
- this.headers = E, this.urlBuilder = new b(e.baseURL), this.headers = e.headers ?? E, this.timeout = e.timeout, this.interceptors = e.interceptors ?? new $();
572
+ this.headers = p, this.urlBuilder = new b(e.baseURL), this.headers = e.headers ?? p, this.timeout = e.timeout, this.interceptors = e.interceptors ?? new $();
577
573
  }
578
574
  /**
579
575
  * Executes an HTTP request with the specified URL and options.
@@ -602,7 +598,10 @@ class V {
602
598
  * @throws Error if an unhandled error occurs during request processing
603
599
  */
604
600
  async request(e) {
605
- const t = p(e.headers, this.headers), s = {
601
+ const t = {
602
+ ...this.headers,
603
+ ...e.headers
604
+ }, s = {
606
605
  ...e,
607
606
  headers: t,
608
607
  timeout: S(e.timeout, this.timeout)
@@ -714,7 +713,7 @@ class V {
714
713
  return this.methodFetch(c.OPTIONS, e, t);
715
714
  }
716
715
  }
717
- const m = "default";
716
+ const E = "default";
718
717
  class H {
719
718
  constructor() {
720
719
  this.registrar = /* @__PURE__ */ new Map();
@@ -788,7 +787,7 @@ class H {
788
787
  * const defaultFetcher = fetcherRegistrar.default;
789
788
  */
790
789
  get default() {
791
- return this.requiredGet(m);
790
+ return this.requiredGet(E);
792
791
  }
793
792
  /**
794
793
  * Set the default Fetcher instance
@@ -799,7 +798,7 @@ class H {
799
798
  * fetcherRegistrar.default = fetcher;
800
799
  */
801
800
  set default(e) {
802
- this.register(m, e);
801
+ this.register(E, e);
803
802
  }
804
803
  /**
805
804
  * Get a copy of all registered fetchers
@@ -816,14 +815,18 @@ class H {
816
815
  }
817
816
  }
818
817
  const k = new H();
818
+ function y(r, e) {
819
+ if (!(r === void 0 && e === void 0))
820
+ return e === void 0 ? r : r === void 0 ? e : { ...r, ...e };
821
+ }
819
822
  function Q(r, e) {
820
823
  if (Object.keys(r).length === 0)
821
824
  return e;
822
825
  if (Object.keys(e).length === 0)
823
826
  return r;
824
827
  const t = {
825
- path: p(r.urlParams?.path, e.urlParams?.path),
826
- query: p(r.urlParams?.query, e.urlParams?.query)
828
+ path: y(r.urlParams?.path, e.urlParams?.path),
829
+ query: y(r.urlParams?.query, e.urlParams?.query)
827
830
  }, s = {
828
831
  ...r.headers,
829
832
  ...e.headers
@@ -861,23 +864,23 @@ class J extends V {
861
864
  super(t), this.name = e, k.register(e, this);
862
865
  }
863
866
  }
864
- const Y = new J(m);
867
+ const Y = new J(E);
865
868
  export {
866
869
  z as ContentTypeHeader,
867
- R as ContentTypeValues,
868
- m as DEFAULT_FETCHER_NAME,
870
+ T as ContentTypeValues,
871
+ E as DEFAULT_FETCHER_NAME,
869
872
  O as DEFAULT_OPTIONS,
870
873
  h as ExchangeError,
871
874
  C as FETCH_INTERCEPTOR_NAME,
872
875
  L as FETCH_INTERCEPTOR_ORDER,
873
876
  j as FetchExchange,
874
877
  D as FetchInterceptor,
875
- T as FetchTimeoutError,
878
+ m as FetchTimeoutError,
876
879
  V as Fetcher,
877
880
  a as FetcherError,
878
881
  H as FetcherRegistrar,
879
882
  c as HttpMethod,
880
- f as HttpStatusValidationError,
883
+ R as HttpStatusValidationError,
881
884
  $ as InterceptorManager,
882
885
  l as InterceptorRegistry,
883
886
  J as NamedFetcher,
@@ -895,7 +898,7 @@ export {
895
898
  Y as fetcher,
896
899
  k as fetcherRegistrar,
897
900
  g as isAbsoluteURL,
898
- p as mergeRecords,
901
+ y as mergeRecords,
899
902
  Q as mergeRequest,
900
903
  S as resolveTimeout,
901
904
  _ as timeoutFetch,