@ahoo-wang/fetcher 3.0.2 → 3.0.5

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/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Fetcher } from './fetcher';
1
2
  /**
2
3
  * Creates a new type by making specified properties of an existing type optional.
3
4
  *
@@ -35,27 +36,228 @@ export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
35
36
  */
36
37
  export type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
37
38
  /**
38
- * Interface representing a named capable entity
39
- * Types implementing this interface must provide a name property
39
+ * Creates a new type by removing all readonly properties from an existing type.
40
+ *
41
+ * This utility type takes a type T and produces a new type that excludes all properties
42
+ * that are marked as readonly in the original type. This is useful when you need to create
43
+ * a mutable version of an interface or when working with data that should be modifiable.
44
+ *
45
+ * @template T - The original type from which to remove readonly properties
46
+ * @returns A new type containing only the mutable (non-readonly) properties of T
47
+ *
48
+ * @example
49
+ * interface User {
50
+ * readonly id: number;
51
+ * name: string;
52
+ * readonly createdAt: Date;
53
+ * email: string;
54
+ * }
55
+ *
56
+ * type MutableUser = RemoveReadonlyFields<User>;
57
+ * // Result: { name: string; email: string; }
58
+ * // 'id' and 'createdAt' are excluded because they are readonly
59
+ *
60
+ * @example
61
+ * // Usage in function parameters
62
+ * function updateUser(user: RemoveReadonlyFields<User>) {
63
+ * // user.id and user.createdAt are not available here
64
+ * user.name = 'New Name'; // OK
65
+ * user.email = 'new@email.com'; // OK
66
+ * }
67
+ */
68
+ export type RemoveReadonlyFields<T> = {
69
+ [K in keyof T as Equal<Pick<T, K>, Readonly<Pick<T, K>>> extends true ? never : K]: T[K];
70
+ };
71
+ /**
72
+ * Utility type to check if two types X and Y are exactly equal.
73
+ *
74
+ * This type uses conditional types and function type inference to determine
75
+ * strict type equality. It returns true if X and Y are identical types,
76
+ * false otherwise. This is particularly useful in mapped types for filtering
77
+ * based on type properties.
78
+ *
79
+ * @template X - First type to compare
80
+ * @template Y - Second type to compare
81
+ * @returns true if X and Y are the same type, false otherwise
82
+ *
83
+ * @internal This is an internal utility type used by other type definitions
84
+ */
85
+ type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
86
+ /**
87
+ * Interface representing a named capable entity.
88
+ *
89
+ * This interface defines a contract for objects that have an identifiable name.
90
+ * Any type implementing this interface must provide a string property called 'name'
91
+ * that uniquely identifies the entity within its context.
92
+ *
93
+ * @interface NamedCapable
94
+ *
95
+ * @property {string} name - A unique identifier for the entity, used for
96
+ * identification, logging, and user-facing display purposes.
97
+ *
98
+ * @example
99
+ * class Service implements NamedCapable {
100
+ * name = 'UserService';
101
+ *
102
+ * async getUser(id: number) {
103
+ * // Implementation
104
+ * }
105
+ * }
106
+ *
107
+ * @example
108
+ * const services: NamedCapable[] = [
109
+ * { name: 'AuthService' },
110
+ * { name: 'DataService' }
111
+ * ];
112
+ *
113
+ * services.forEach(service => {
114
+ * console.log(`Initializing ${service.name}`);
115
+ * });
40
116
  */
41
117
  export interface NamedCapable {
42
118
  /**
43
- * The name of the entity
119
+ * The name of the entity.
120
+ *
121
+ * This property serves as a unique identifier for the implementing object.
122
+ * It should be descriptive and follow consistent naming conventions
123
+ * within the application context.
44
124
  */
45
125
  name: string;
46
126
  }
47
127
  /**
48
- * Global extension of Response interface
49
- * Adds type-safe json() method support to Response objects
128
+ * Global extension of the native Response interface.
129
+ *
130
+ * This declaration augments the standard Web API Response interface to provide
131
+ * enhanced type safety for JSON parsing operations. The extended json() method
132
+ * allows specifying the expected return type, enabling better TypeScript
133
+ * inference and compile-time type checking.
134
+ *
135
+ * @interface Response
50
136
  */
51
137
  declare global {
52
138
  interface Response {
53
139
  /**
54
- * Parse response body as JSON in a type-safe manner
55
- * @template T The type of returned data, defaults to any
56
- * @returns Promise<T> The parsed JSON data
140
+ * Parses the response body as JSON with type safety.
141
+ *
142
+ * This method extends the native Response.json() method to support generic
143
+ * type parameters, allowing developers to specify the expected shape of
144
+ * the parsed JSON data. This provides compile-time type checking and
145
+ * better IDE support.
146
+ *
147
+ * @template T - The expected type of the parsed JSON data. Defaults to 'any' for backward compatibility.
148
+ * @returns {Promise<T>} A promise that resolves to the parsed JSON data of type T.
149
+ *
150
+ * @throws {SyntaxError} If the response body is not valid JSON.
151
+ * @throws {TypeError} If the response has no body or the body cannot be parsed.
152
+ *
153
+ * @example
154
+ * interface User {
155
+ * id: number;
156
+ * name: string;
157
+ * email: string;
158
+ * }
159
+ *
160
+ * const response = await fetch('/api/user/123');
161
+ * const user: User = await response.json<User>();
162
+ * console.log(user.name); // TypeScript knows this is a string
163
+ *
164
+ * @example
165
+ * // Without type parameter (defaults to any)
166
+ * const data = await response.json();
167
+ * // data is of type 'any'
168
+ *
169
+ * @example
170
+ * // Error handling
171
+ * try {
172
+ * const result = await response.json<{ success: boolean; data: string[] }>();
173
+ * if (result.success) {
174
+ * result.data.forEach(item => console.log(item));
175
+ * }
176
+ * } catch (error) {
177
+ * console.error('Failed to parse JSON:', error);
178
+ * }
57
179
  */
58
180
  json<T = any>(): Promise<T>;
59
181
  }
60
182
  }
183
+ /**
184
+ * Interface for configuring Fetcher instances.
185
+ *
186
+ * This interface defines a contract for objects that can configure a Fetcher instance
187
+ * with specific interceptors, middleware, or other customizations. Implementations of
188
+ * this interface provide a standardized way to apply configuration to Fetcher objects,
189
+ * enabling modular and reusable configuration patterns.
190
+ *
191
+ * @interface FetcherConfigurer
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * class AuthConfigurer implements FetcherConfigurer {
196
+ * configure(fetcher: Fetcher): void {
197
+ * // Add authentication interceptors
198
+ * fetcher.interceptors.request.use(new AuthRequestInterceptor());
199
+ * fetcher.interceptors.response.use(new AuthResponseInterceptor());
200
+ * }
201
+ * }
202
+ *
203
+ * // Usage
204
+ * const fetcher = new Fetcher({ baseURL: '/api' });
205
+ * const configurer = new AuthConfigurer();
206
+ * configurer.configure(fetcher);
207
+ * ```
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * // Multiple configurers can be applied
212
+ * const configurers: FetcherConfigurer[] = [
213
+ * new AuthConfigurer(),
214
+ * new LoggingConfigurer(),
215
+ * new RetryConfigurer()
216
+ * ];
217
+ *
218
+ * const fetcher = new Fetcher({ baseURL: '/api' });
219
+ * configurers.forEach(configurer => configurer.configure(fetcher));
220
+ * ```
221
+ */
222
+ export interface FetcherConfigurer {
223
+ /**
224
+ * Configures the provided Fetcher instance.
225
+ *
226
+ * This method should apply all necessary configuration to the Fetcher instance,
227
+ * such as adding interceptors, setting default headers, or configuring other
228
+ * behavior. The method should be idempotent - calling it multiple times on
229
+ * the same Fetcher instance should not cause issues.
230
+ *
231
+ * @param fetcher - The Fetcher instance to configure
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * applyTo(fetcher: Fetcher): void {
236
+ * // Add request interceptor for authentication
237
+ * fetcher.interceptors.request.use({
238
+ * onFulfilled: config => {
239
+ * config.headers = {
240
+ * ...config.headers,
241
+ * 'Authorization': `Bearer ${getToken()}`
242
+ * };
243
+ * return config;
244
+ * }
245
+ * });
246
+ *
247
+ * // Add response interceptor for error handling
248
+ * fetcher.interceptors.response.use({
249
+ * onRejected: error => {
250
+ * if (error.response?.status === 401) {
251
+ * // Handle unauthorized
252
+ * redirectToLogin();
253
+ * }
254
+ * return Promise.reject(error);
255
+ * }
256
+ * });
257
+ * }
258
+ * ```
259
+ */
260
+ applyTo(fetcher: Fetcher): void;
261
+ }
262
+ export {};
61
263
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACvD,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEvB;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,QAAQ;QAChB;;;;WAIG;QACH,IAAI,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;KAC7B;CACF"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACvD,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;KACnC,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACjE,KAAK,GACL,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,IACb,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAC/D,IAAI,GACJ,KAAK,CAAC;AAEZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,QAAQ;QAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAwCG;QACH,IAAI,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;KAC7B;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACjC"}
@@ -54,8 +54,8 @@ export declare class UrlBuilder implements BaseURLCapable {
54
54
  *
55
55
  * This is typically the root of your API endpoint (e.g., 'https://api.example.com').
56
56
  */
57
- readonly baseURL: string;
58
- readonly urlTemplateResolver: UrlTemplateResolver;
57
+ baseURL: string;
58
+ urlTemplateResolver: UrlTemplateResolver;
59
59
  /**
60
60
  * Initializes a new UrlBuilder instance.
61
61
  *
@@ -1 +1 @@
1
- {"version":3,"file":"urlBuilder.d.ts","sourceRoot":"","sources":["../src/urlBuilder.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAEL,KAAK,mBAAmB,EACxB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,cAAc;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAElD;;;;;;;;;;;;;;;;OAgBG;gBACS,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAKhE;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM;IAc9C;;;;;;;;OAQG;IACH,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;CAGjD;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;CACxB"}
1
+ {"version":3,"file":"urlBuilder.d.ts","sourceRoot":"","sources":["../src/urlBuilder.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAEL,KAAK,mBAAmB,EACxB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,cAAc;IAC/C;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,mBAAmB,CAAC;IAEzC;;;;;;;;;;;;;;;;OAgBG;gBACS,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAKhE;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM;IAc9C;;;;;;;;OAQG;IACH,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;CAGjD;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;CACxB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahoo-wang/fetcher",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "description": "Fetcher is not just another HTTP client—it's a complete ecosystem designed for modern web development with native LLM\nstreaming API support. Built on the native Fetch API, Fetcher provides an Axios-like experience with powerful features\nwhile maintaining an incredibly small footprint.",
5
5
  "keywords": [
6
6
  "fetch",