@zayne-labs/callapi 1.0.0-rc.8 → 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
@@ -1,47 +1,47 @@
1
- # CallApi
2
-
3
- [![Build Size](https://img.shields.io/bundlephobia/minzip/@zayne-labs/callapi?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=@zayne-labs/callapi)[![Version](https://img.shields.io/npm/v/@zayne-labs/callapi?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@zayne-labs/callapi)
4
-
5
- CallApi Fetch is an extra-lightweight wrapper over fetch that provides quality of life improvements beyond the bare fetch api, while keeping the API familiar.
6
-
7
- It takes in a url and a request options object, just like fetch, but with some additional options to make your life easier. Check out the [API Reference](https://zayne-callapi.netlify.app/api-reference) for a quick look at each option.
8
-
9
- # Docs
10
-
11
- [View Documentation website](https://zayne-callapi.netlify.app)
12
-
13
- ## Installing `CallApi`
14
-
15
- ### Through npm (recommended)
16
-
17
- ```bash
18
- # npm
19
- npm install @zayne-labs/callapi
20
-
21
- # pnpm
22
- pnpm add @zayne-labs/callapi
23
- ```
24
-
25
- Then you can use it by importing it in your JavaScript file.
26
-
27
- ```js
28
- import { callApi } from "@zayne-labs/callapi";
29
- ```
30
-
31
- ### Using `CallApi` without `npm`
32
-
33
- You can import callApi directly into JavaScript through a CDN.
34
-
35
- To do this, you first need to set your `script`'s type to `module`, then import `callApi`.
36
-
37
- ```html
38
- <script type="module">
39
- import { callApi } from "https://esm.run/@zayne-labs/callapi";
40
- </script>
41
-
42
- <!-- Locked to a specific version -->
43
- <script type="module">
44
- import { callApi } from "https://esm.run/@zayne-labs/callapi@0.3.2";
45
- </script>
46
- ```
47
-
1
+ # CallApi
2
+
3
+ [![Build Size](https://img.shields.io/bundlephobia/minzip/@zayne-labs/callapi?label=bundle%20size&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/result?p=@zayne-labs/callapi)[![Version](https://img.shields.io/npm/v/@zayne-labs/callapi?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@zayne-labs/callapi)
4
+
5
+ CallApi Fetch is an extra-lightweight wrapper over fetch that provides quality of life improvements beyond the bare fetch api, while keeping the API familiar.
6
+
7
+ It takes in a url and a request options object, just like fetch, but with some additional options to make your life easier. Check out the [API Reference](https://zayne-labs-callapi.netlify.app/api-reference) for a quick look at each option.
8
+
9
+ # Docs
10
+
11
+ [View Documentation website](https://zayne-callapi.netlify.app)
12
+
13
+ ## Installing `CallApi`
14
+
15
+ ### Through npm (recommended)
16
+
17
+ ```bash
18
+ # npm
19
+ npm install @zayne-labs/callapi
20
+
21
+ # pnpm
22
+ pnpm add @zayne-labs/callapi
23
+ ```
24
+
25
+ Then you can use it by importing it in your JavaScript file.
26
+
27
+ ```js
28
+ import { callApi } from "@zayne-labs/callapi";
29
+ ```
30
+
31
+ ### Using `CallApi` without `npm`
32
+
33
+ You can import callApi directly into JavaScript through a CDN.
34
+
35
+ To do this, you first need to set your `script`'s type to `module`, then import `callApi`.
36
+
37
+ ```html
38
+ <script type="module">
39
+ import { callApi } from "https://esm.run/@zayne-labs/callapi";
40
+ </script>
41
+
42
+ <!-- Locked to a specific version -->
43
+ <script type="module">
44
+ import { callApi } from "https://esm.run/@zayne-labs/callapi@0.3.2";
45
+ </script>
46
+ ```
47
+
@@ -0,0 +1,436 @@
1
+ type AnyString = string & {
2
+ placeholder?: never;
3
+ };
4
+ type AnyNumber = number & {
5
+ placeholder?: never;
6
+ };
7
+ type AnyFunction<TResult = any> = (...args: any[]) => TResult;
8
+ type UnmaskType<TValue> = {
9
+ _: TValue;
10
+ }["_"];
11
+ type Awaitable<TValue> = Promise<TValue> | TValue;
12
+ type CommonRequestHeaders = "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Allow-Origin" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Age" | "Allow" | "Cache-Control" | "Clear-Site-Data" | "Content-Disposition" | "Content-Encoding" | "Content-Language" | "Content-Length" | "Content-Location" | "Content-Range" | "Content-Security-Policy-Report-Only" | "Content-Security-Policy" | "Cookie" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Resource-Policy" | "Date" | "ETag" | "Expires" | "Last-Modified" | "Location" | "Permissions-Policy" | "Pragma" | "Retry-After" | "Save-Data" | "Sec-CH-Prefers-Color-Scheme" | "Sec-CH-Prefers-Reduced-Motion" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "Sec-CH-UA-Form-Factor" | "Sec-CH-UA-Full-Version-List" | "Sec-CH-UA-Full-Version" | "Sec-CH-UA-Mobile" | "Sec-CH-UA-Model" | "Sec-CH-UA-Platform-Version" | "Sec-CH-UA-Platform" | "Sec-CH-UA-WoW64" | "Sec-CH-UA" | "Sec-Fetch-Dest" | "Sec-Fetch-Mode" | "Sec-Fetch-Site" | "Sec-Fetch-User" | "Sec-GPC" | "Server-Timing" | "Server" | "Service-Worker-Navigation-Preload" | "Set-Cookie" | "Strict-Transport-Security" | "Timing-Allow-Origin" | "Trailer" | "Transfer-Encoding" | "Upgrade" | "Vary" | "Warning" | "WWW-Authenticate" | "X-Content-Type-Options" | "X-DNS-Prefetch-Control" | "X-Frame-Options" | "X-Permitted-Cross-Domain-Policies" | "X-Powered-By" | "X-Robots-Tag" | "X-XSS-Protection";
13
+ type CommonContentTypes = "application/epub+zip" | "application/gzip" | "application/json" | "application/ld+json" | "application/octet-stream" | "application/ogg" | "application/pdf" | "application/rtf" | "application/vnd.ms-fontobject" | "application/wasm" | "application/xhtml+xml" | "application/xml" | "application/zip" | "audio/aac" | "audio/mpeg" | "audio/ogg" | "audio/opus" | "audio/webm" | "audio/x-midi" | "font/otf" | "font/ttf" | "font/woff" | "font/woff2" | "image/avif" | "image/bmp" | "image/gif" | "image/jpeg" | "image/png" | "image/svg+xml" | "image/tiff" | "image/webp" | "image/x-icon" | "model/gltf-binary" | "model/gltf+json" | "text/calendar" | "text/css" | "text/csv" | "text/html" | "text/javascript" | "text/plain" | "video/3gpp" | "video/3gpp2" | "video/av1" | "video/mp2t" | "video/mp4" | "video/mpeg" | "video/ogg" | "video/webm" | "video/x-msvideo";
14
+
15
+ type PluginInitContext<TData = unknown, TErrorData = unknown> = {
16
+ initURL: string;
17
+ options: CombinedCallApiExtraOptions<TData, TErrorData>;
18
+ request: Omit<CallApiRequestOptionsForHooks, "fullURL">;
19
+ };
20
+ type CallApiPlugin<TData = unknown, TErrorData = unknown> = {
21
+ /**
22
+ * @description A description for the plugin
23
+ */
24
+ description?: string;
25
+ /**
26
+ * Hooks/Interceptors for the plugin
27
+ */
28
+ hooks?: Interceptors<TData, TErrorData>;
29
+ /**
30
+ * @description A unique id for the plugin
31
+ */
32
+ id: string;
33
+ /**
34
+ * @description A function that will be called when the plugin is
35
+ * initialized. This will be called before the any
36
+ * of the other internal functions.
37
+ */
38
+ init?: (context: PluginInitContext<TData, TErrorData>) => Awaitable<{
39
+ options?: CombinedCallApiExtraOptions<TData, TErrorData>;
40
+ request: CallApiRequestOptionsForHooks;
41
+ url?: string;
42
+ }> | Awaitable<void>;
43
+ /**
44
+ * @description A name for the plugin
45
+ */
46
+ name: string;
47
+ /**
48
+ * @description A version for the plugin
49
+ */
50
+ version?: string;
51
+ };
52
+ declare const definePlugin: <TPlugin extends CallApiPlugin<never, never> | AnyFunction<CallApiPlugin<never, never>>>(plugin: TPlugin) => TPlugin;
53
+
54
+ type ToQueryStringFn = {
55
+ (params: CallApiConfig["query"]): string | null;
56
+ (params: Required<CallApiConfig>["query"]): string;
57
+ };
58
+ declare const toQueryString: ToQueryStringFn;
59
+ declare const getResponseType: <TResponse>(response: Response, parser?: Required<CallApiExtraOptions>["responseParser"]) => {
60
+ arrayBuffer: () => Promise<TResponse>;
61
+ blob: () => Promise<TResponse>;
62
+ formData: () => Promise<TResponse>;
63
+ json: () => Promise<Record<string, unknown> | TResponse>;
64
+ stream: () => ReadableStream<Uint8Array<ArrayBufferLike>> | null;
65
+ text: () => Promise<TResponse>;
66
+ };
67
+ declare const isHTTPError: <TErrorData>(error: ErrorObjectUnion<TErrorData> | null) => error is PossibleHTTPError<TErrorData>;
68
+ type ErrorDetails<TErrorResponse> = {
69
+ defaultErrorMessage: string;
70
+ errorData: TErrorResponse;
71
+ response: Response;
72
+ };
73
+ type ErrorOptions = {
74
+ cause?: unknown;
75
+ };
76
+ declare class HTTPError<TErrorResponse = Record<string, unknown>> extends Error {
77
+ errorData: ErrorDetails<TErrorResponse>["errorData"];
78
+ isHTTPError: boolean;
79
+ name: "HTTPError";
80
+ response: ErrorDetails<TErrorResponse>["response"];
81
+ constructor(errorDetails: ErrorDetails<TErrorResponse>, errorOptions?: ErrorOptions);
82
+ }
83
+ declare const isHTTPErrorInstance: <TErrorResponse>(error: unknown) => error is HTTPError<TErrorResponse>;
84
+
85
+ declare const fetchSpecificKeys: ("body" | "cache" | "credentials" | "headers" | "integrity" | "keepalive" | "method" | "mode" | "priority" | "redirect" | "referrer" | "referrerPolicy" | "signal" | "window")[];
86
+
87
+ type FetchSpecificKeysUnion = Exclude<(typeof fetchSpecificKeys)[number], "body" | "headers" | "method">;
88
+ interface CallApiRequestOptions extends Pick<RequestInit, FetchSpecificKeysUnion> {
89
+ /**
90
+ * @description Optional body of the request, can be a object or any other supported body type.
91
+ */
92
+ body?: Record<string, unknown> | RequestInit["body"];
93
+ /**
94
+ * @description Headers to be used in the request.
95
+ */
96
+ headers?: Record<"Content-Type", CommonContentTypes> | Record<CommonRequestHeaders | AnyString, string> | RequestInit["headers"];
97
+ /**
98
+ * @description HTTP method for the request.
99
+ * @default "GET"
100
+ */
101
+ method?: "DELETE" | "GET" | "PATCH" | "POST" | "PUT" | AnyString;
102
+ }
103
+ interface CallApiRequestOptionsForHooks extends CallApiRequestOptions {
104
+ /**
105
+ * @description Resolved request URL
106
+ */
107
+ readonly fullURL?: string;
108
+ headers?: Record<CommonRequestHeaders | AnyString, string>;
109
+ }
110
+ interface Register {
111
+ }
112
+ type R_Meta = Register extends {
113
+ meta?: infer TMeta extends Record<string, unknown>;
114
+ } ? TMeta : never;
115
+ interface Interceptors<TData = unknown, TErrorData = unknown> {
116
+ /**
117
+ * @description Interceptor to be called when any error occurs within the request/response lifecyle, regardless of whether the error is from the api or not.
118
+ * It is basically a combination of `onRequestError` and `onResponseError` interceptors
119
+ */
120
+ onError?: (context: ErrorContext<TErrorData>) => Awaitable<unknown>;
121
+ /**
122
+ * @description Interceptor to be called just before the request is made, allowing for modifications or additional operations.
123
+ */
124
+ onRequest?: (context: RequestContext) => Awaitable<unknown>;
125
+ /**
126
+ * @description Interceptor to be called when an error occurs during the fetch request.
127
+ */
128
+ onRequestError?: (context: RequestErrorContext) => Awaitable<unknown>;
129
+ /**
130
+ * @description Interceptor to be called when any response is received from the api, whether successful or not
131
+ */
132
+ onResponse?: (context: ResponseContext<TData, TErrorData>) => Awaitable<unknown>;
133
+ /**
134
+ * @description Interceptor to be called when an error response is received from the api.
135
+ */
136
+ onResponseError?: (context: ResponseErrorContext<TErrorData>) => Awaitable<unknown>;
137
+ /**
138
+ * @description Interceptor to be called when a successful response is received from the api.
139
+ */
140
+ onSuccess?: (context: SuccessContext<TData>) => Awaitable<unknown>;
141
+ }
142
+ interface InterceptorsArray<TData = unknown, TErrorData = unknown> {
143
+ /**
144
+ * @description Interceptor to be called when any error occurs within the request/response lifecyle, regardless of whether the error is from the api or not.
145
+ * It is basically a combination of `onRequestError` and `onResponseError` interceptors
146
+ */
147
+ onError?: Array<Interceptors<TData, TErrorData>["onError"]>;
148
+ /**
149
+ * @description Interceptor to be called just before the request is made, allowing for modifications or additional operations.
150
+ */
151
+ onRequest?: Array<Interceptors<TData, TErrorData>["onRequest"]>;
152
+ /**
153
+ * @description Interceptor to be called when an error occurs during the fetch request.
154
+ */
155
+ onRequestError?: Array<Interceptors<TData, TErrorData>["onRequestError"]>;
156
+ /**
157
+ * @description Interceptor to be called when any response is received from the api, whether successful or not
158
+ */
159
+ onResponse?: Array<Interceptors<TData, TErrorData>["onResponse"]>;
160
+ /**
161
+ * @description Interceptor to be called when an error response is received from the api.
162
+ */
163
+ onResponseError?: Array<Interceptors<TData, TErrorData>["onResponseError"]>;
164
+ /**
165
+ * @description Interceptor to be called when a successful response is received from the api.
166
+ */
167
+ onSuccess?: Array<Interceptors<TData, TErrorData>["onSuccess"]>;
168
+ }
169
+ type FetchImpl = UnmaskType<(input: string | Request | URL, init?: RequestInit) => Promise<Response>>;
170
+ type CallApiPluginArray<TData, TErrorData> = Array<CallApiPlugin<TData, TErrorData>>;
171
+ type CallApiPluginFn<TData, TErrorData> = (context: PluginInitContext<TData, TErrorData>) => Array<CallApiPlugin<TData, TErrorData>>;
172
+ type ExtraOptions<TData = unknown, TErrorData = unknown, TResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> = (Interceptors<TData, TErrorData> | InterceptorsArray<TData, TErrorData>) & {
173
+ /**
174
+ * @description Authorization header value.
175
+ */
176
+ auth?: string | {
177
+ bearer: string | null;
178
+ token?: never;
179
+ } | {
180
+ bearer?: never;
181
+ token: string | null;
182
+ } | null;
183
+ /**
184
+ * @description Base URL to be prepended to all request URLs
185
+ */
186
+ baseURL?: string;
187
+ /**
188
+ * @description Custom function to serialize the body object into a string.
189
+ */
190
+ bodySerializer?: (bodyData: Record<string, unknown>) => string;
191
+ /**
192
+ * @description Whether or not to clone the response, so response.json() and the like, can be read again else where.
193
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Response/clone
194
+ * @default false
195
+ */
196
+ cloneResponse?: boolean;
197
+ /**
198
+ * @description Custom fetch implementation
199
+ */
200
+ customFetchImpl?: FetchImpl;
201
+ /**
202
+ * @description Defines the deduplication strategy for the request, can be set to "none" | "defer" | "cancel".
203
+ * - If set to "none", deduplication is disabled.
204
+ *
205
+ * - If set to "cancel"(default), the previous pending request with the same request key will be cancelled and lets the new request through.
206
+ *
207
+ * - If set to "defer", all new request with the same request key will be share the same response, until the previous one is completed.
208
+ * @default "cancel"
209
+ */
210
+ dedupeStrategy?: "cancel" | "defer" | "none";
211
+ /**
212
+ * @description Default error message to use if none is provided from a response.
213
+ * @default "Failed to fetch data from server!"
214
+ */
215
+ defaultErrorMessage?: string;
216
+ /**
217
+ * @description URL to be used in the request.
218
+ */
219
+ readonly initURL?: string;
220
+ /**
221
+ * @description Defines the mode in which the merged interceptors are executed, can be set to "parallel" | "sequential".
222
+ * - If set to "parallel", both plugin and main interceptors will be executed in parallel.
223
+ * - If set to "sequential", the plugin interceptors will be executed first, followed by the main interceptor.
224
+ * @default "parallel"
225
+ */
226
+ mergedInterceptorsExecutionMode?: "parallel" | "sequential";
227
+ /**
228
+ * @description - Controls what order in which the mergedInterceptors execute
229
+ * @default "mainInterceptorLast"
230
+ */
231
+ mergedInterceptorsExecutionOrder?: "mainInterceptorFirst" | "mainInterceptorLast";
232
+ /**
233
+ * @description - An optional field you can fill with additional information,
234
+ * to associate with the request, typically used for logging or tracing.
235
+ *
236
+ * - A good use case for this, would be to use the info to handle specific cases in any of the shared interceptors.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * const callMainApi = callApi.create({
241
+ * baseURL: "https://main-api.com",
242
+ * onResponseError: ({ response, options }) => {
243
+ * if (options.meta?.userId) {
244
+ * console.error(`User ${options.meta.userId} made an error`);
245
+ * }
246
+ * },
247
+ * });
248
+ *
249
+ * const response = await callMainApi({
250
+ * url: "https://example.com/api/data",
251
+ * meta: { userId: "123" },
252
+ * });
253
+ * ```
254
+ */
255
+ meta?: R_Meta;
256
+ /**
257
+ * @description Params to be appended to the URL (i.e: /:id)
258
+ */
259
+ params?: Record<string, boolean | number | string> | Array<boolean | number | string>;
260
+ /**
261
+ * @description An array of CallApi plugins. It allows you to extend the behavior of the library.
262
+ */
263
+ plugins?: CallApiPluginArray<TData, TErrorData>;
264
+ /**
265
+ * @description Query parameters to append to the URL.
266
+ */
267
+ query?: Record<string, boolean | number | string>;
268
+ /**
269
+ * @description Custom request key to be used to identify a request in the fetch deduplication strategy.
270
+ * @default the full request url + string formed from the request options
271
+ */
272
+ requestKey?: string;
273
+ /**
274
+ * @description Custom function to validate the response error data, stemming from the api.
275
+ * This only runs if the api actually sends back error status codes, else it will be ignored, in which case you should only use the `responseValidator` option.
276
+ */
277
+ responseErrorValidator?: (data: unknown) => TErrorData;
278
+ /**
279
+ * @description Custom function to parse the response string into a object.
280
+ */
281
+ responseParser?: (responseString: string) => Awaitable<Record<string, unknown>>;
282
+ /**
283
+ * @description Expected response type, affects how response is parsed
284
+ * @default "json"
285
+ */
286
+ responseType?: keyof ReturnType<typeof getResponseType>;
287
+ /**
288
+ * @description Custom function to validate the response data.
289
+ */
290
+ responseValidator?: (data: unknown) => TData;
291
+ /**
292
+ * @description Mode of the result, can influence how results are handled or returned.
293
+ * Can be set to "all" | "onlySuccess" | "onlyError" | "onlyResponse".
294
+ * @default "all"
295
+ */
296
+ resultMode?: TResultMode;
297
+ /**
298
+ * @description Number of retry attempts for failed requests
299
+ * @default 0
300
+ */
301
+ retryAttempts?: number;
302
+ /**
303
+ * @description HTTP status codes that trigger a retry
304
+ * @default [409, 425, 429, 500, 502, 503, 504]
305
+ */
306
+ retryCodes?: Array<409 | 425 | 429 | 500 | 502 | 503 | 504 | AnyNumber>;
307
+ /**
308
+ * @description Delay between retries in milliseconds
309
+ * @default 500
310
+ */
311
+ retryDelay?: number;
312
+ /**
313
+ * HTTP methods that are allowed to retry
314
+ * @default ["GET", "POST"]
315
+ */
316
+ retryMethods?: Array<"GET" | "POST" | AnyString>;
317
+ /**
318
+ * If true or the function returns true, throws errors instead of returning them
319
+ * The function is passed the error object and can be used to conditionally throw the error
320
+ * @default false
321
+ */
322
+ throwOnError?: boolean | ((context: ErrorContext<TErrorData>) => boolean);
323
+ /**
324
+ * @description Request timeout in milliseconds
325
+ */
326
+ timeout?: number;
327
+ };
328
+ declare const optionsEnumToOmitFromBase: ["extend", "override", "requestKey"];
329
+ interface BaseCallApiExtraOptions<TBaseData = unknown, TBaseErrorData = unknown, TBaseResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> extends Omit<CallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode>, typeof optionsEnumToOmitFromBase[number]> {
330
+ /**
331
+ * @description An array of CallApi plugins. It allows you to extend the behavior of the library.
332
+ */
333
+ plugins?: CallApiPluginArray<TBaseData, TBaseErrorData> | CallApiPluginFn<TBaseData, TBaseErrorData>;
334
+ }
335
+ declare const optionsEnumToOmitFromInstance: ["plugins"];
336
+ interface CallApiExtraOptions<TData = unknown, TErrorData = unknown, TResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> extends Omit<ExtraOptions<TData, TErrorData, TResultMode>, (typeof optionsEnumToOmitFromInstance)[number]> {
337
+ /**
338
+ * @description Options that should extend the base options.
339
+ */
340
+ extend?: Pick<ExtraOptions<TData, TErrorData, TResultMode>, (typeof optionsEnumToOmitFromInstance)[number]>;
341
+ /**
342
+ * @description Options that should override the base options.
343
+ */
344
+ override?: Pick<ExtraOptions<TData, TErrorData, TResultMode>, (typeof optionsEnumToOmitFromInstance)[number]>;
345
+ }
346
+ interface CombinedCallApiExtraOptions<TData = unknown, TErrorData = unknown, TResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> extends BaseCallApiExtraOptions<TData, TErrorData, TResultMode>, CallApiExtraOptions<TData, TErrorData, TResultMode> {
347
+ }
348
+ interface BaseCallApiConfig<TBaseData = unknown, TBaseErrorData = unknown, TBaseResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> extends CallApiRequestOptions, BaseCallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode> {
349
+ }
350
+ interface CallApiConfig<TData = unknown, TErrorData = unknown, TResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> extends CallApiRequestOptions, CallApiExtraOptions<TData, TErrorData, TResultMode> {
351
+ }
352
+ type CallApiParameters<TData = unknown, TErrorData = unknown, TResultMode extends CallApiResultModeUnion = CallApiResultModeUnion> = [initURL: string, config?: CallApiConfig<TData, TErrorData, TResultMode>];
353
+ type RequestContext = UnmaskType<{
354
+ options: CombinedCallApiExtraOptions;
355
+ request: CallApiRequestOptionsForHooks;
356
+ }>;
357
+ type ResponseContext<TData, TErrorData> = UnmaskType<{
358
+ data: TData;
359
+ error: null;
360
+ options: CombinedCallApiExtraOptions;
361
+ request: CallApiRequestOptionsForHooks;
362
+ response: Response;
363
+ } | {
364
+ data: null;
365
+ error: PossibleHTTPError<TErrorData>;
366
+ options: CombinedCallApiExtraOptions;
367
+ request: CallApiRequestOptionsForHooks;
368
+ response: Response;
369
+ }>;
370
+ type SuccessContext<TData> = UnmaskType<{
371
+ data: TData;
372
+ options: CombinedCallApiExtraOptions;
373
+ request: CallApiRequestOptionsForHooks;
374
+ response: Response;
375
+ }>;
376
+ type RequestErrorContext = UnmaskType<{
377
+ error: PossibleJavaScriptError;
378
+ options: CombinedCallApiExtraOptions;
379
+ request: CallApiRequestOptionsForHooks;
380
+ }>;
381
+ type ResponseErrorContext<TErrorData> = UnmaskType<{
382
+ error: PossibleHTTPError<TErrorData>;
383
+ options: CombinedCallApiExtraOptions;
384
+ request: CallApiRequestOptionsForHooks;
385
+ response: Response;
386
+ }>;
387
+ type ErrorContext<TErrorData> = UnmaskType<{
388
+ error: PossibleHTTPError<TErrorData>;
389
+ options: CombinedCallApiExtraOptions;
390
+ request: CallApiRequestOptionsForHooks;
391
+ response: Response;
392
+ } | {
393
+ error: PossibleJavaScriptError;
394
+ options: CombinedCallApiExtraOptions;
395
+ request: CallApiRequestOptionsForHooks;
396
+ response: null;
397
+ }>;
398
+ type PossibleJavascriptErrorNames = "AbortError" | "Error" | "SyntaxError" | "TimeoutError" | "TypeError" | (`${string}Error` & {});
399
+ type PossibleJavaScriptError = UnmaskType<{
400
+ errorData: DOMException | Error | SyntaxError | TypeError;
401
+ message: string;
402
+ name: PossibleJavascriptErrorNames;
403
+ }>;
404
+ type PossibleHTTPError<TErrorData> = UnmaskType<{
405
+ errorData: TErrorData;
406
+ message: string;
407
+ name: "HTTPError";
408
+ }>;
409
+ type ErrorObjectUnion<TErrorData = unknown> = PossibleHTTPError<TErrorData> | PossibleJavaScriptError;
410
+ type CallApiResultSuccessVariant<TData> = {
411
+ data: TData;
412
+ error: null;
413
+ response: Response;
414
+ };
415
+ type CallApiResultErrorVariant<TErrorData> = {
416
+ data: null;
417
+ error: PossibleHTTPError<TErrorData>;
418
+ response: Response;
419
+ } | {
420
+ data: null;
421
+ error: PossibleJavaScriptError;
422
+ response: null;
423
+ };
424
+ type ResultModeMap<TData = unknown, TErrorData = unknown> = {
425
+ all: CallApiResultSuccessVariant<TData> | CallApiResultErrorVariant<TErrorData>;
426
+ onlyError: CallApiResultErrorVariant<TErrorData>["error"] | null;
427
+ onlyResponse: CallApiResultSuccessVariant<TData>["response"] | null;
428
+ onlySuccess: CallApiResultSuccessVariant<TData>["data"] | null;
429
+ onlySuccessWithException: CallApiResultSuccessVariant<TData>["data"];
430
+ };
431
+ type CallApiResultModeUnion = {
432
+ [Key in keyof ResultModeMap]: Key;
433
+ }[keyof ResultModeMap] | undefined;
434
+ type GetCallApiResult<TData, TErrorData, TResultMode> = TErrorData extends false ? ResultModeMap<TData, TErrorData>["onlySuccessWithException"] : undefined extends TResultMode ? ResultModeMap<TData, TErrorData>["all"] : TResultMode extends NonNullable<CallApiResultModeUnion> ? ResultModeMap<TData, TErrorData>[TResultMode] : never;
435
+
436
+ export { type BaseCallApiConfig as B, type CallApiResultModeUnion as C, type ErrorContext as E, type GetCallApiResult as G, HTTPError as H, type PluginInitContext as P, type Register as R, type SuccessContext as S, type CallApiConfig as a, type CallApiPlugin as b, type BaseCallApiExtraOptions as c, definePlugin as d, type CallApiExtraOptions as e, type CallApiParameters as f, type CallApiRequestOptions as g, type CallApiRequestOptionsForHooks as h, type CallApiResultErrorVariant as i, type CallApiResultSuccessVariant as j, type CombinedCallApiExtraOptions as k, type PossibleJavascriptErrorNames as l, type RequestContext as m, type RequestErrorContext as n, type ResponseContext as o, type ResponseErrorContext as p, isHTTPError as q, isHTTPErrorInstance as r, toQueryString as t };
@@ -1 +1 @@
1
- "use strict";var e,r=Object.defineProperty,t=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,n={};((e,t)=>{for(var o in t)r(e,o,{get:t[o],enumerable:!0})})(n,{callApi:()=>O,createFetchClient:()=>q}),module.exports=(e=n,((e,n,a,i)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let l of o(n))s.call(e,l)||l===a||r(e,l,{get:()=>n[l],enumerable:!(i=t(n,l))||i.enumerable});return e})(r({},"__esModule",{value:!0}),e));var a=e=>Array.isArray(e),i=e=>!("object"!=typeof e||null===e||e instanceof FormData||a(e)),l=e=>"string"==typeof e,u="&",c=(e,r)=>{if(!r)return e;const t=(o=r)?new URLSearchParams(o).toString():(console.error("toQueryString:","No query params provided!"),null);var o;return 0===t?.length?e:e.endsWith("?")?`${e}${t}`:e.includes("?")?`${e}${u}${t}`:`${e}?${t}`},p=(e,r,t)=>{const o=((e,r)=>{if(!r)return e;let t=e;if(a(r)){const e=t.split("/").filter((e=>e.startsWith(":")));for(const[o,s]of e.entries()){const e=r[o];t=t.replace(s,e)}return t}for(const[e,o]of Object.entries(r))t=t.replace(`:${e}`,String(o));return t})(e,r);return c(o,t)},d=e=>!e||i(e)?e:Object.fromEntries(a(e)?e:e.entries()),f=Object.keys({408:"Request Timeout",409:"Conflict",425:"Too Early",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"}).map(Number),y=["GET"],m=["body","integrity","method","headers","signal","cache","redirect","window","credentials","keepalive","referrer","priority","mode","referrerPolicy"],h=(e,r)=>{const t=Object.entries(e).filter((([e])=>!r.includes(e)));return Object.fromEntries(t)},g=(e,r)=>{const t=new Set(r),o=Object.entries(e).filter((([e])=>t.has(e)));return Object.fromEntries(o)},E=(e,r,t,o)=>{if(a(e)&&t){return async t=>{if(!r)return;const s=[...e,r],n=[...new Set(s)];if("sequential"===o)for(const e of n)await e(t);"parallel"===o&&await Promise.all(n.map((e=>e(t))))}}return r??e},b=(e,r,t)=>{const o=((e,r)=>({arrayBuffer:()=>e.arrayBuffer(),blob:()=>e.blob(),formData:()=>e.formData(),json:async()=>r?r(await e.text()):e.json(),text:()=>e.text()}))(e,t);if(!Object.hasOwn(o,r))throw new Error(`Invalid response type: ${r}`);return o[r]()},w=class extends Error{errorData;isHTTPError=!0;name="HTTPError";response;constructor(e,r){const{defaultErrorMessage:t,errorData:o,response:s}=e;super(o.message??t,r),this.errorData=o,this.response=s}},M=e=>e instanceof w||i(e)&&"HTTPError"===e.name&&!0===e.isHTTPError,R=e=>{if(0===e)return;const{promise:r,resolve:t}=Promise.withResolvers();return setTimeout(t,e),r},q=(e={})=>{const[r,t]=(e=>[g(e,m),h(e,[...m,"requestKey"])])(e),{body:o,headers:s,signal:n,...a}=r,{onError:c,onRequest:O,onRequestError:S,onResponse:T,onResponseError:$,...D}=t,j=new Map,P=async(e,r={})=>{const[t,q]=(e=>[g(e,m),h(e,m)])(r),{body:v=o,headers:x,signal:I=n,...A}=t,{onError:C,onRequest:k,onRequestError:B,onResponse:N,onResponseError:z,...G}=q,H={baseURL:"",bodySerializer:JSON.stringify,dedupeStrategy:"cancel",defaultErrorMessage:"Failed to fetch data from server!",mergedInterceptorsExecutionMode:"parallel",responseType:"json",resultMode:"all",retries:0,retryCodes:f,retryDelay:0,retryMethods:y,shouldMergeInterceptors:!0,...D,...G},U={...{onError:E(c,C,H.shouldMergeInterceptors,H.mergedInterceptorsExecutionMode),onRequest:E(O,k,H.shouldMergeInterceptors,H.mergedInterceptorsExecutionMode),onRequestError:E(S,B,H.shouldMergeInterceptors,H.mergedInterceptorsExecutionMode),onResponse:E(T,N,H.shouldMergeInterceptors,H.mergedInterceptorsExecutionMode),onResponseError:E($,z,H.shouldMergeInterceptors,H.mergedInterceptorsExecutionMode)},...H},F={method:"GET",body:i(v)?U.bodySerializer(v):v,headers:s||x||i(v)||U.auth?{...i(v)&&{Accept:"application/json","Content-Type":"application/json"},...(L=v,l(L)&&L.includes("=")&&{"Content-Type":"application/x-www-form-urlencoded"}),...(l(U.auth)||null===U.auth)&&{Authorization:`Bearer ${U.auth}`},...i(U.auth)&&{Authorization:"bearer"in U.auth?`Bearer ${U.auth.bearer}`:`Token ${U.auth.token}`},...d(s),...d(x)}:void 0,...a,...A};var L;const J="cancel"===U.dedupeStrategy||"defer"===U.dedupeStrategy,K=U.requestKey??(J?((e,r)=>`${e} ${u} ${JSON.stringify(r)}`)(e,{...F,...U}):null);null!=K&&await R(.1);const V=K?j:null,W=V?.get(K);if(W&&"cancel"===U.dedupeStrategy){const r=new DOMException(`Request aborted as another request to the endpoint: ${e}, with the same request options was initiated.`,"AbortError");W.controller.abort(r)}const _=new AbortController,Q=U.timeout?AbortSignal.timeout(U.timeout):null,X=AbortSignal.any([_.signal,...Q?[Q]:[],...I?[I]:[]]),Y={signal:X,...F};try{await(U.onRequest?.({options:U,request:Y}));const t=W&&"defer"===U.dedupeStrategy?W.responsePromise:fetch(`${U.baseURL}${p(e,U.params,U.query)}`,Y);V?.set(K,{controller:_,responsePromise:t});const o=await t;if(!o.ok&&!X.aborted&&U.retries>0&&U.retryCodes.includes(o.status)&&U.retryMethods.includes(Y.method))return await R(U.retryDelay),await P(e,{...r,retries:U.retries-1});const s="defer"===U.dedupeStrategy||U.shouldCloneResponse;if(!o.ok){const e=await b(s?o.clone():o,U.responseType,U.responseParser);throw new w({defaultErrorMessage:U.defaultErrorMessage,errorData:e,response:o})}const n=await b(s?o.clone():o,U.responseType,U.responseParser),a=U.responseValidator?U.responseValidator(n):n;return await(U.onResponse?.({data:a,options:U,request:Y,response:U.shouldCloneResponse?o.clone():o})),(e=>{const{response:r,resultMode:t,successData:o}=e,s={data:o,error:null,response:r};return t?{all:s,onlyError:s.error,onlyResponse:s.response,onlySuccess:s.data}[t]:s})({response:o,resultMode:U.resultMode,successData:a})}catch(e){const r=(e=>{const{defaultErrorMessage:r,error:t,resultMode:o}=e;let s;if(M(t)){const{errorData:e,message:o=r,name:n,response:a}=t;s={data:null,error:{errorData:e,message:o,name:n},response:a}}if(t){const{message:e,name:r}=t;s={data:null,error:{errorData:t,message:e,name:r},response:null}}return o?{all:s,onlyError:s.error,onlyResponse:s.response,onlySuccess:s.data}[o]:s})({defaultErrorMessage:U.defaultErrorMessage,error:e,resultMode:U.resultMode}),t=(e=>"function"==typeof e)(U.throwOnError)?U.throwOnError(r.error,U):U.throwOnError;if(t)throw e;if(e instanceof DOMException&&"TimeoutError"===e.name){const t=`Request timed out after ${U.timeout}ms`;return console.error(`${e.name}:`,t),{...r,message:t}}if(e instanceof DOMException&&"AbortError"===e.name){const{message:t,name:o}=e;return console.error(`${o}:`,t),r}if(M(e)){const{errorData:t,response:o}=e;return await Promise.all([U.onResponseError?.({errorData:t,options:U,request:Y,response:U.shouldCloneResponse?o.clone():o}),U.onError?.({error:e,options:U,request:Y,response:o})]),r}return await Promise.all([U.onRequestError?.({error:e,options:U,request:Y}),U.onError?.({error:r.error,options:U,request:Y,response:null})]),r}finally{V?.delete(K)}};return P.create=q,P},O=q();//# sourceMappingURL=index.cjs.map
1
+ "use strict";var e,r=Object.defineProperty,o=Object.getOwnPropertyDescriptor,t=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,n={};((e,o)=>{for(var t in o)r(e,t,{get:o[t],enumerable:!0})})(n,{callApi:()=>D,createFetchClient:()=>$,definePlugin:()=>p}),module.exports=(e=n,((e,n,a,i)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let l of t(n))s.call(e,l)||l===a||r(e,l,{get:()=>n[l],enumerable:!(i=o(n,l))||i.enumerable});return e})(r({},"__esModule",{value:!0}),e));var a=e=>Array.isArray(e),i=e=>{if(!(e=>"object"==typeof e&&null!==e)(e))return!1;const r=Object.getPrototypeOf(e);return(null==r||r===Object.prototype||null===Object.getPrototypeOf(r))&&!(Symbol.toStringTag in e)},l=e=>"function"==typeof e,u=e=>"string"==typeof e,c=async e=>{const{initURL:r,options:o,request:t}=e,s={onError:new Set([]),onRequest:new Set([]),onRequestError:new Set([]),onResponse:new Set([]),onResponseError:new Set([]),onSuccess:new Set([])},n=()=>{s.onRequest.add(o.onRequest),s.onRequestError.add(o.onRequestError),s.onResponse.add(o.onResponse),s.onResponseError.add(o.onResponseError),s.onSuccess.add(o.onSuccess),s.onError.add(o.onError)};"mainInterceptorFirst"===o.mergedInterceptorsExecutionOrder&&n();const a=l(o.plugins)?[o.plugins({initURL:r,options:o,request:t}),o.extend?.plugins??[]].flat():[o.plugins??[],o.extend?.plugins??[]].flat();let c=r,p=o,d=t;const f=async e=>{if(!e)return;const s=await e({initURL:r,options:o,request:t});i(s)&&(u(s.url)&&(c=s.url),i(s.request)&&(d=s.request),i(s.options)&&(p=s.options))};for(const e of o.override?.plugins??a)await f(e.init),e.hooks&&(y=e.hooks,s.onRequest.add(y.onRequest),s.onRequestError.add(y.onRequestError),s.onResponse.add(y.onResponse),s.onResponseError.add(y.onResponseError),s.onSuccess.add(y.onSuccess),s.onError.add(y.onError));var y;o.mergedInterceptorsExecutionOrder&&"mainInterceptorLast"!==o.mergedInterceptorsExecutionOrder||n();const E=e=>{const r=((e,r)=>async o=>{if("sequential"!==r){if("parallel"===r){const r=[...e];await Promise.all(r.map((e=>e?.(o))))}}else for(const r of e)await(r?.(o))})(e,o.mergedInterceptorsExecutionMode);return r};return{interceptors:{onError:E([...s.onError].flat()),onRequest:E([...s.onRequest].flat()),onRequestError:E([...s.onRequestError].flat()),onResponse:E([...s.onResponse].flat()),onResponseError:E([...s.onResponseError].flat()),onSuccess:E([...s.onSuccess].flat())},resolvedOptions:p,resolvedRequestOptions:d,url:c}},p=e=>e,d=["extend","override","requestKey"],f=["plugins"],y=["body","integrity","method","headers","signal","cache","redirect","window","credentials","keepalive","referrer","priority","mode","referrerPolicy"],E={408:"Request Timeout",409:"Conflict",425:"Too Early",429:"Too Many Requests",500:"Internal Server Error",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout"},m=["GET"],R=Object.keys(E).map(Number),g=(e,r)=>{const o={},t=new Set(r);for(const[r,s]of Object.entries(e))t.has(r)||(o[r]=s);return o},w=(e,r)=>{const o={},t=new Set(r);for(const[r,s]of Object.entries(e))t.has(r)&&(o[r]=s);return o},h=e=>!e||i(e)?e:Object.fromEntries(e),q=e=>{const{auth:r,baseHeaders:o,body:t,headers:s}=e;if(!Boolean(o||s||t||r))return;const n={...(u(r)||null===r)&&{Authorization:`Bearer ${r}`},...i(r)&&{Authorization:"bearer"in r?`Bearer ${r.bearer}`:`Token ${r.token}`},...h(o),...h(s)};return u(a=t)&&a.includes("=")?(n["Content-Type"]="application/x-www-form-urlencoded",n):((i(t)||u(t)&&t.startsWith("{"))&&(n["Content-Type"]="application/json",n.Accept="application/json"),n);var a},b=(e,r)=>a(e)?[e,r].flat():r??e,S=(...e)=>Promise.all(e),O=async(e,r,o,t)=>{const s=((e,r)=>({arrayBuffer:()=>e.arrayBuffer(),blob:()=>e.blob(),formData:()=>e.formData(),json:async()=>{if(r){const o=await e.text();return r(o)}return e.json()},stream:()=>e.body,text:()=>e.text()}))(e,o);if(!Object.hasOwn(s,r))throw new Error(`Invalid response type: ${r}`);const n=await s[r]();return t?t(n):n},v=e=>{const{defaultErrorMessage:r,error:o,message:t,resultMode:s}=e;let n={data:null,error:{errorData:o,message:t??o.message,name:o.name},response:null};if(M(o)){const{errorData:e,message:t=r,name:s,response:a}=o;n={data:null,error:{errorData:e,message:t,name:s},response:a}}return{apiDetails:n,generalErrorResult:{all:n,onlyError:n.error,onlyResponse:n.response,onlySuccess:n.data,onlySuccessWithException:n.data}[s??"all"],resolveCustomErrorInfo:({message:r})=>v({...e,message:r}).generalErrorResult}},T=class extends Error{errorData;isHTTPError=!0;name="HTTPError";response;constructor(e,r){const{defaultErrorMessage:o,errorData:t,response:s}=e;super(t?.message??o,r),this.errorData=t,this.response=s,Error.captureStackTrace(this,this.constructor)}},M=e=>e instanceof T||i(e)&&"HTTPError"===e.name&&!0===e.isHTTPError,j=e=>{if(0===e)return;const{promise:r,resolve:o}=(()=>{let e,r;return{promise:new Promise(((o,t)=>{r=o,e=t})),reject:e,resolve:r}})();return setTimeout(o,e),r},x=(e,r)=>{if(!r)return e;const o=(t=r)?new URLSearchParams(t).toString():(console.error("toQueryString:","No query params provided!"),null);var t;return 0===o?.length?e:e.endsWith("?")?`${e}${o}`:e.includes("?")?`${e}&${o}`:`${e}?${o}`},P=(e,r,o)=>{const t=((e,r)=>{if(!r)return e;let o=e;if(a(r)){const e=o.split("/").filter((e=>e.startsWith(":")));for(const[t,s]of e.entries()){const e=r[t];o=o.replace(s,e)}return o}for(const[e,t]of Object.entries(r))o=o.replace(`:${e}`,String(t));return o})(e,r);return x(t,o)},$=(e={})=>{const[r,o]=(e=>[w(e,y),g(e,[...y,...d])])(e),{body:t,headers:s,signal:n,...a}=r,u=new Map,p=async(...e)=>{const[r,d]=e,[E,h]=(e=>[w(e,y),g(e,[...y,...f])])(d??{}),{body:x=t,headers:$,signal:D=n,...A}=E,I={baseURL:"",bodySerializer:JSON.stringify,dedupeStrategy:"cancel",defaultErrorMessage:"Failed to fetch data from server!",mergedInterceptorsExecutionMode:"parallel",mergedInterceptorsExecutionOrder:"mainInterceptorLast",responseType:"json",resultMode:"all",retryAttempts:0,retryCodes:R,retryDelay:0,retryMethods:m,...o,...h,onError:b(o.onError,h.onError),onRequest:b(o.onRequest,h.onRequest),onRequestError:b(o.onRequestError,h.onRequestError),onResponse:b(o.onResponse,h.onResponse),onResponseError:b(o.onResponseError,h.onResponseError),onSuccess:b(o.onSuccess,h.onSuccess)},{interceptors:L,resolvedOptions:k,resolvedRequestOptions:U,url:C}=await c({initURL:r,options:I,request:{...a,...A}}),H={...k,...L,initURL:r},B={body:i(x)?H.bodySerializer(x):x,method:"GET",...U},N=`${H.baseURL}${P(C,H.params,H.query)}`,K="cancel"===H.dedupeStrategy||"defer"===H.dedupeStrategy,W=H.requestKey??((e,r)=>r.shouldHaveRequestKey?`${e}-${JSON.stringify(r)}`:null)(N,{shouldHaveRequestKey:K,...U,...H});null!=W&&await j(.1);const z=null!=W?u:null,F=z?.get(W);if(F&&"cancel"===H.dedupeStrategy){const e=H.requestKey?`Duplicate request detected - Aborting previous request with key '${W}' as a new request was initiated`:`Duplicate request detected - Aborting previous request to '${N}' as a new request with identical options was initiated`,r=new DOMException(e,"AbortError");F.controller.abort(r)}const G=new AbortController,J=null!=H.timeout?(V=H.timeout,AbortSignal.timeout(V)):null;var V;const _=((...e)=>AbortSignal.any(e.filter(Boolean)))(G.signal,J,D),Q={fullURL:N,signal:_,...B},X=(e=>{if(e)return e;if("undefined"!=typeof globalThis&&l(globalThis.fetch))return globalThis.fetch;throw new Error("No fetch implementation found")})(H.customFetchImpl);try{await S(H.onRequest({options:H,request:Q})),Q.headers=q({auth:H.auth,baseHeaders:s??$,body:x,headers:Q.headers});const e=F&&"defer"===H.dedupeStrategy?F.responsePromise:X(N,Q);z?.set(W,{controller:G,responsePromise:e});const o=await e;if(!o.ok&&!_.aborted&&H.retryAttempts>0&&H.retryCodes.includes(o.status)&&H.retryMethods.includes(Q.method))return await j(H.retryDelay),await p(r,{...d,retryAttempts:H.retryAttempts-1});const t="defer"===H.dedupeStrategy||"onlyResponse"===H.resultMode||H.cloneResponse;if(!o.ok){const e=await O(t?o.clone():o,H.responseType,H.responseParser,H.responseErrorValidator);throw new T({defaultErrorMessage:H.defaultErrorMessage,errorData:e,response:o})}const n=await O(t?o.clone():o,H.responseType,H.responseParser,H.responseValidator);return await S(H.onSuccess({data:n,options:H,request:Q,response:H.cloneResponse?o.clone():o}),H.onResponse({data:n,error:null,options:H,request:Q,response:H.cloneResponse?o.clone():o})),(e=>{const{data:r,response:o,resultMode:t}=e,s={data:r,error:null,response:o};return t?{all:s,onlyError:s.error,onlyResponse:s.response,onlySuccess:s.data,onlySuccessWithException:s.data}[t]:s})({data:n,response:o,resultMode:H.resultMode})}catch(e){const{apiDetails:r,generalErrorResult:o,resolveCustomErrorInfo:t}=v({defaultErrorMessage:H.defaultErrorMessage,error:e,resultMode:H.resultMode}),s=l(H.throwOnError)?H.throwOnError({error:r.error,options:H,request:Q,response:r.response}):H.throwOnError,n=()=>{if(s)throw r.error};if(M(e)){const{response:r}=e,t=o.error;return await S(H.onResponseError({error:t,options:H,request:Q,response:H.cloneResponse?r.clone():r}),H.onError({error:t,options:H,request:Q,response:H.cloneResponse?r.clone():r}),H.onResponse({data:null,error:t,options:H,request:Q,response:H.cloneResponse?r.clone():r})),n(),o}if(e instanceof DOMException&&"TimeoutError"===e.name){const r=`Request timed out after ${H.timeout}ms`;return console.error(`${e.name}:`,r),n(),t({message:r})}if(e instanceof DOMException&&"AbortError"===e.name){const{message:r,name:t}=e;return console.error(`${t}:`,r),n(),o}const a=o.error;return await S(H.onRequestError({error:a,options:H,request:Q}),H.onError({error:a,options:H,request:Q,response:null})),n(),o}finally{z?.delete(W)}};return p.create=$,p},D=$();//# sourceMappingURL=index.cjs.map