@zayne-labs/callapi 1.3.6 → 1.4.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 +2 -2
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +8 -7
- package/dist/cjs/options/index.cjs +1 -1
- package/dist/cjs/options/index.cjs.map +1 -1
- package/dist/cjs/options/index.d.cts +10 -9
- package/dist/cjs/{plugins-DXl13OeA.d.cts → types-CNYLI9wS.d.cts} +148 -132
- package/dist/cjs/utils/index.cjs.map +1 -1
- package/dist/cjs/utils/index.d.cts +3 -2
- package/dist/esm/chunk-KABMV5OF.js +1 -0
- package/dist/esm/chunk-KABMV5OF.js.map +1 -0
- package/dist/esm/chunk-UMFL27YA.js +1 -0
- package/dist/esm/chunk-UMFL27YA.js.map +1 -0
- package/dist/esm/index.d.ts +8 -7
- package/dist/esm/index.js +1 -1
- package/dist/esm/options/index.d.ts +10 -9
- package/dist/esm/options/index.js +1 -1
- package/dist/esm/options/index.js.map +1 -1
- package/dist/esm/{plugins-DXl13OeA.d.ts → types-CNYLI9wS.d.ts} +148 -132
- package/dist/esm/utils/index.d.ts +3 -2
- package/dist/esm/utils/index.js +1 -1
- package/package.json +2 -1
- package/dist/esm/chunk-5YQFYNEZ.js +0 -1
- package/dist/esm/chunk-5YQFYNEZ.js.map +0 -1
- package/dist/esm/chunk-IWFRA3QE.js +0 -1
- package/dist/esm/chunk-IWFRA3QE.js.map +0 -1
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
z_placeholder?: never;
|
|
3
|
-
};
|
|
4
|
-
type AnyNumber = number & {
|
|
5
|
-
z_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" | AnyString;
|
|
13
|
-
type CommonAuthorizationHeaders = `${"Basic" | "Bearer" | "Token"} ${string}`;
|
|
14
|
-
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" | AnyString;
|
|
1
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
15
2
|
|
|
16
3
|
type ValueOrFunctionResult<TValue> = TValue | (() => TValue);
|
|
17
4
|
/**
|
|
@@ -62,29 +49,44 @@ type CustomAuth = {
|
|
|
62
49
|
};
|
|
63
50
|
type Auth = BearerOrTokenAuth | BasicAuth | CustomAuth;
|
|
64
51
|
|
|
52
|
+
type AnyString = string & {
|
|
53
|
+
z_placeholder?: never;
|
|
54
|
+
};
|
|
55
|
+
type AnyNumber = number & {
|
|
56
|
+
z_placeholder?: never;
|
|
57
|
+
};
|
|
58
|
+
type AnyFunction<TResult = any> = (...args: any[]) => TResult;
|
|
59
|
+
type UnmaskType<TValue> = {
|
|
60
|
+
_: TValue;
|
|
61
|
+
}["_"];
|
|
62
|
+
type Awaitable<TValue> = Promise<TValue> | TValue;
|
|
63
|
+
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" | AnyString;
|
|
64
|
+
type CommonAuthorizationHeaders = `${"Basic" | "Bearer" | "Token"} ${string}`;
|
|
65
|
+
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" | AnyString;
|
|
66
|
+
|
|
65
67
|
type RetryCondition<TErrorData> = (context: ErrorContext<TErrorData>) => boolean | Promise<boolean>;
|
|
66
68
|
interface RetryOptions<TErrorData> {
|
|
67
69
|
/**
|
|
68
|
-
*
|
|
70
|
+
* Keeps track of the number of times the request has already been retried
|
|
69
71
|
* @deprecated This property is used internally to track retries. Please abstain from modifying it.
|
|
70
72
|
*/
|
|
71
73
|
readonly "~retryCount"?: number;
|
|
72
74
|
/**
|
|
73
|
-
*
|
|
75
|
+
* Number of allowed retry attempts on HTTP errors
|
|
74
76
|
* @default 0
|
|
75
77
|
*/
|
|
76
78
|
retryAttempts?: number;
|
|
77
79
|
/**
|
|
78
|
-
*
|
|
80
|
+
* Callback whose return value determines if a request should be retried or not
|
|
79
81
|
*/
|
|
80
82
|
retryCondition?: RetryCondition<TErrorData>;
|
|
81
83
|
/**
|
|
82
|
-
*
|
|
84
|
+
* Delay between retries in milliseconds
|
|
83
85
|
* @default 1000
|
|
84
86
|
*/
|
|
85
87
|
retryDelay?: number;
|
|
86
88
|
/**
|
|
87
|
-
*
|
|
89
|
+
* Maximum delay in milliseconds. Only applies to exponential strategy
|
|
88
90
|
* @default 10000
|
|
89
91
|
*/
|
|
90
92
|
retryMaxDelay?: number;
|
|
@@ -94,17 +96,96 @@ interface RetryOptions<TErrorData> {
|
|
|
94
96
|
*/
|
|
95
97
|
retryMethods?: Array<"GET" | "POST" | AnyString>;
|
|
96
98
|
/**
|
|
97
|
-
*
|
|
99
|
+
* HTTP status codes that trigger a retry
|
|
98
100
|
* @default [409, 425, 429, 500, 502, 503, 504]
|
|
99
101
|
*/
|
|
100
102
|
retryStatusCodes?: Array<409 | 425 | 429 | 500 | 502 | 503 | 504 | AnyNumber>;
|
|
101
103
|
/**
|
|
102
|
-
*
|
|
104
|
+
* Strategy to use when retrying
|
|
103
105
|
* @default "linear"
|
|
104
106
|
*/
|
|
105
107
|
retryStrategy?: "exponential" | "linear";
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
interface Schemas {
|
|
111
|
+
/**
|
|
112
|
+
* The schema to use for validating the response data.
|
|
113
|
+
*/
|
|
114
|
+
data?: StandardSchemaV1;
|
|
115
|
+
/**
|
|
116
|
+
* The schema to use for validating the response error data.
|
|
117
|
+
*/
|
|
118
|
+
errorData?: StandardSchemaV1;
|
|
119
|
+
}
|
|
120
|
+
interface Validators<TData = unknown, TErrorData = unknown> {
|
|
121
|
+
/**
|
|
122
|
+
* Custom function to validate the response data.
|
|
123
|
+
*/
|
|
124
|
+
data?: (data: unknown) => TData;
|
|
125
|
+
/**
|
|
126
|
+
* Custom function to validate the response error data, stemming from the api.
|
|
127
|
+
* 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.
|
|
128
|
+
*/
|
|
129
|
+
errorData?: (data: unknown) => TErrorData;
|
|
130
|
+
}
|
|
131
|
+
type InferSchemaResult<TSchema extends StandardSchemaV1 | undefined, TData> = TSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TSchema> : TData;
|
|
132
|
+
|
|
133
|
+
type ToQueryStringFn = {
|
|
134
|
+
(params: CallApiConfig["query"]): string | null;
|
|
135
|
+
(params: Required<CallApiConfig>["query"]): string;
|
|
136
|
+
};
|
|
137
|
+
declare const toQueryString: ToQueryStringFn;
|
|
138
|
+
declare const getResponseType: <TResponse>(response: Response, parser?: Required<CallApiExtraOptions>["responseParser"]) => {
|
|
139
|
+
arrayBuffer: () => Promise<TResponse>;
|
|
140
|
+
blob: () => Promise<TResponse>;
|
|
141
|
+
formData: () => Promise<TResponse>;
|
|
142
|
+
json: () => Promise<Record<string, unknown> | TResponse>;
|
|
143
|
+
stream: () => ReadableStream<Uint8Array<ArrayBufferLike>> | null;
|
|
144
|
+
text: () => Promise<TResponse>;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
type UnionToIntersection<TUnion> = (TUnion extends unknown ? (param: TUnion) => void : never) extends (param: infer TParam) => void ? TParam : never;
|
|
148
|
+
type InferPluginOptions<TPluginArray extends CallApiPlugin[]> = TPluginArray extends Array<infer TPlugin extends CallApiPlugin> ? TPlugin["createExtraOptions"] extends (...params: never[]) => infer TResult ? UnionToIntersection<TResult> : NonNullable<unknown> : NonNullable<unknown>;
|
|
149
|
+
type PluginInitContext<TMoreOptions = DefaultMoreOptions> = WithMoreOptions<TMoreOptions> & {
|
|
150
|
+
initURL: string;
|
|
151
|
+
options: CombinedCallApiExtraOptions;
|
|
152
|
+
request: CallApiRequestOptionsForHooks;
|
|
153
|
+
};
|
|
154
|
+
type PluginInitResult = Partial<Omit<PluginInitContext, "request"> & {
|
|
155
|
+
request: CallApiRequestOptions;
|
|
156
|
+
}>;
|
|
157
|
+
type CallApiPlugin = {
|
|
158
|
+
/**
|
|
159
|
+
* Defines additional options that can be passed to callApi
|
|
160
|
+
*/
|
|
161
|
+
createExtraOptions?: (...params: never[]) => unknown;
|
|
162
|
+
/**
|
|
163
|
+
* A description for the plugin
|
|
164
|
+
*/
|
|
165
|
+
description?: string;
|
|
166
|
+
/**
|
|
167
|
+
* Hooks / Interceptors for the plugin
|
|
168
|
+
*/
|
|
169
|
+
hooks?: InterceptorsOrInterceptorArray;
|
|
170
|
+
/**
|
|
171
|
+
* A unique id for the plugin
|
|
172
|
+
*/
|
|
173
|
+
id: string;
|
|
174
|
+
/**
|
|
175
|
+
* A function that will be called when the plugin is initialized. This will be called before the any of the other internal functions.
|
|
176
|
+
*/
|
|
177
|
+
init?: (context: PluginInitContext) => Awaitable<PluginInitResult> | Awaitable<void>;
|
|
178
|
+
/**
|
|
179
|
+
* A name for the plugin
|
|
180
|
+
*/
|
|
181
|
+
name: string;
|
|
182
|
+
/**
|
|
183
|
+
* A version for the plugin
|
|
184
|
+
*/
|
|
185
|
+
version?: string;
|
|
186
|
+
};
|
|
187
|
+
declare const definePlugin: <TPlugin extends CallApiPlugin | AnyFunction<CallApiPlugin> = CallApiPlugin>(plugin: TPlugin) => TPlugin;
|
|
188
|
+
|
|
108
189
|
declare const fetchSpecificKeys: ("headers" | "body" | "cache" | "credentials" | "integrity" | "keepalive" | "method" | "mode" | "priority" | "redirect" | "referrer" | "referrerPolicy" | "signal" | "window")[];
|
|
109
190
|
declare const defaultRetryMethods: ("GET" | "POST")[];
|
|
110
191
|
declare const defaultRetryStatusCodes: Required<BaseCallApiConfig>["retryStatusCodes"];
|
|
@@ -112,18 +193,18 @@ declare const defaultRetryStatusCodes: Required<BaseCallApiConfig>["retryStatusC
|
|
|
112
193
|
type FetchSpecificKeysUnion = Exclude<(typeof fetchSpecificKeys)[number], "body" | "headers" | "method">;
|
|
113
194
|
interface CallApiRequestOptions extends Pick<RequestInit, FetchSpecificKeysUnion> {
|
|
114
195
|
/**
|
|
115
|
-
*
|
|
196
|
+
* Optional body of the request, can be a object or any other supported body type.
|
|
116
197
|
*/
|
|
117
198
|
body?: Record<string, unknown> | RequestInit["body"];
|
|
118
199
|
/**
|
|
119
|
-
*
|
|
200
|
+
* Headers to be used in the request.
|
|
120
201
|
*/
|
|
121
202
|
headers?: Record<"Authorization", CommonAuthorizationHeaders> | Record<"Content-Type", CommonContentTypes> | Record<CommonRequestHeaders, string | undefined> | Record<string, string | undefined> | RequestInit["headers"];
|
|
122
203
|
/**
|
|
123
|
-
*
|
|
204
|
+
* HTTP method for the request.
|
|
124
205
|
* @default "GET"
|
|
125
206
|
*/
|
|
126
|
-
method?: "DELETE" | "GET" | "PATCH" | "POST" | "PUT" | AnyString;
|
|
207
|
+
method?: "CONNECT" | "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT" | "TRACE" | AnyString;
|
|
127
208
|
}
|
|
128
209
|
interface CallApiRequestOptionsForHooks extends Omit<CallApiRequestOptions, "headers"> {
|
|
129
210
|
headers?: Record<string, string | undefined>;
|
|
@@ -137,32 +218,32 @@ type WithMoreOptions<TMoreOptions = DefaultMoreOptions> = {
|
|
|
137
218
|
};
|
|
138
219
|
interface Interceptors<TData = DefaultDataType, TErrorData = DefaultDataType, TMoreOptions = DefaultMoreOptions> {
|
|
139
220
|
/**
|
|
140
|
-
*
|
|
221
|
+
* Interceptor that will be called when any error occurs within the request/response lifecycle, regardless of whether the error is from the api or not.
|
|
141
222
|
* It is basically a combination of `onRequestError` and `onResponseError` interceptors
|
|
142
223
|
*/
|
|
143
224
|
onError?: (context: ErrorContext<TErrorData> & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
144
225
|
/**
|
|
145
|
-
*
|
|
226
|
+
* Interceptor that will be called just before the request is made, allowing for modifications or additional operations.
|
|
146
227
|
*/
|
|
147
228
|
onRequest?: (context: RequestContext & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
148
229
|
/**
|
|
149
|
-
*
|
|
230
|
+
* Interceptor that will be called when an error occurs during the fetch request.
|
|
150
231
|
*/
|
|
151
232
|
onRequestError?: (context: RequestErrorContext & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
152
233
|
/**
|
|
153
|
-
*
|
|
234
|
+
* Interceptor that will be called when any response is received from the api, whether successful or not
|
|
154
235
|
*/
|
|
155
236
|
onResponse?: (context: ResponseContext<TData, TErrorData> & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
156
237
|
/**
|
|
157
|
-
*
|
|
238
|
+
* Interceptor that will be called when an error response is received from the api.
|
|
158
239
|
*/
|
|
159
240
|
onResponseError?: (context: ResponseErrorContext<TErrorData> & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
160
241
|
/**
|
|
161
|
-
*
|
|
242
|
+
* Interceptor that will be called when a request is retried.
|
|
162
243
|
*/
|
|
163
244
|
onRetry?: (response: ErrorContext<TErrorData> & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
164
245
|
/**
|
|
165
|
-
*
|
|
246
|
+
* Interceptor that will be called when a successful response is received from the api.
|
|
166
247
|
*/
|
|
167
248
|
onSuccess?: (context: SuccessContext<TData> & WithMoreOptions<TMoreOptions>) => Awaitable<unknown>;
|
|
168
249
|
}
|
|
@@ -173,36 +254,36 @@ type FetchImpl = UnmaskType<(input: string | Request | URL, init?: RequestInit)
|
|
|
173
254
|
type Meta = Register extends {
|
|
174
255
|
meta?: infer TMeta extends Record<string, unknown>;
|
|
175
256
|
} ? TMeta : never;
|
|
176
|
-
type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] =
|
|
257
|
+
type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] = never[], TSchemas extends Schemas = DefaultMoreOptions> = {
|
|
177
258
|
/**
|
|
178
|
-
*
|
|
259
|
+
* Authorization header value.
|
|
179
260
|
*/
|
|
180
261
|
auth?: string | Auth | null;
|
|
181
262
|
/**
|
|
182
|
-
*
|
|
263
|
+
* Base URL to be prepended to all request URLs
|
|
183
264
|
*/
|
|
184
265
|
baseURL?: string;
|
|
185
266
|
/**
|
|
186
|
-
*
|
|
267
|
+
* Custom function to serialize the body object into a string.
|
|
187
268
|
*/
|
|
188
269
|
bodySerializer?: (bodyData: Record<string, unknown>) => string;
|
|
189
270
|
/**
|
|
190
|
-
*
|
|
271
|
+
* Whether or not to clone the response, so response.json() and the like, can be read again else where.
|
|
191
272
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Response/clone
|
|
192
273
|
* @default false
|
|
193
274
|
*/
|
|
194
275
|
cloneResponse?: boolean;
|
|
195
276
|
/**
|
|
196
|
-
*
|
|
277
|
+
* Custom fetch implementation
|
|
197
278
|
*/
|
|
198
279
|
customFetchImpl?: FetchImpl;
|
|
199
280
|
/**
|
|
200
|
-
*
|
|
281
|
+
* Custom request key to be used to identify a request in the fetch deduplication strategy.
|
|
201
282
|
* @default the full request url + string formed from the request options
|
|
202
283
|
*/
|
|
203
284
|
dedupeKey?: string;
|
|
204
285
|
/**
|
|
205
|
-
*
|
|
286
|
+
* Defines the deduplication strategy for the request, can be set to "none" | "defer" | "cancel".
|
|
206
287
|
* - If set to "cancel", the previous pending request with the same request key will be cancelled and lets the new request through.
|
|
207
288
|
* - 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
289
|
* - If set to "none", deduplication is disabled.
|
|
@@ -210,32 +291,32 @@ type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResult
|
|
|
210
291
|
*/
|
|
211
292
|
dedupeStrategy?: "cancel" | "defer" | "none";
|
|
212
293
|
/**
|
|
213
|
-
*
|
|
294
|
+
* Default error message to use if none is provided from a response.
|
|
214
295
|
* @default "Failed to fetch data from server!"
|
|
215
296
|
*/
|
|
216
297
|
defaultErrorMessage?: string;
|
|
217
298
|
/**
|
|
218
|
-
*
|
|
299
|
+
* Resolved request URL
|
|
219
300
|
*/
|
|
220
301
|
readonly fullURL?: string;
|
|
221
302
|
/**
|
|
222
|
-
*
|
|
303
|
+
* URL to be used in the request.
|
|
223
304
|
*/
|
|
224
305
|
readonly initURL?: string;
|
|
225
306
|
/**
|
|
226
|
-
*
|
|
307
|
+
* Defines the mode in which the merged hooks are executed, can be set to "parallel" | "sequential".
|
|
227
308
|
* - If set to "parallel", main and plugin hooks will be executed in parallel.
|
|
228
309
|
* - If set to "sequential", the plugin hooks will be executed first, followed by the main hook.
|
|
229
310
|
* @default "parallel"
|
|
230
311
|
*/
|
|
231
312
|
mergedHooksExecutionMode?: "parallel" | "sequential";
|
|
232
313
|
/**
|
|
233
|
-
*
|
|
314
|
+
* - Controls what order in which the merged hooks execute
|
|
234
315
|
* @default "mainHooksLast"
|
|
235
316
|
*/
|
|
236
317
|
mergedHooksExecutionOrder?: "mainHooksAfterPlugins" | "mainHooksBeforePlugins";
|
|
237
318
|
/**
|
|
238
|
-
*
|
|
319
|
+
* - An optional field you can fill with additional information,
|
|
239
320
|
* to associate with the request, typically used for logging or tracing.
|
|
240
321
|
*
|
|
241
322
|
* - A good use case for this, would be to use the info to handle specific cases in any of the shared interceptors.
|
|
@@ -259,41 +340,33 @@ type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResult
|
|
|
259
340
|
*/
|
|
260
341
|
meta?: Meta;
|
|
261
342
|
/**
|
|
262
|
-
*
|
|
343
|
+
* Params to be appended to the URL (i.e: /:id)
|
|
263
344
|
*/
|
|
264
345
|
params?: Record<string, boolean | number | string> | Array<boolean | number | string>;
|
|
265
346
|
/**
|
|
266
|
-
*
|
|
347
|
+
* An array of CallApi plugins. It allows you to extend the behavior of the library.
|
|
267
348
|
*/
|
|
268
349
|
plugins?: TPluginArray | ((context: PluginInitContext) => TPluginArray);
|
|
269
350
|
/**
|
|
270
|
-
*
|
|
351
|
+
* Query parameters to append to the URL.
|
|
271
352
|
*/
|
|
272
353
|
query?: Record<string, boolean | number | string>;
|
|
273
354
|
/**
|
|
274
|
-
*
|
|
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.
|
|
355
|
+
* Custom function to parse the response string into a object.
|
|
280
356
|
*/
|
|
281
357
|
responseParser?: (responseString: string) => Awaitable<Record<string, unknown>>;
|
|
282
358
|
/**
|
|
283
|
-
*
|
|
359
|
+
* Expected response type, affects how response is parsed
|
|
284
360
|
* @default "json"
|
|
285
361
|
*/
|
|
286
362
|
responseType?: keyof ReturnType<typeof getResponseType>;
|
|
287
363
|
/**
|
|
288
|
-
*
|
|
289
|
-
*/
|
|
290
|
-
responseValidator?: (data: unknown) => TData;
|
|
291
|
-
/**
|
|
292
|
-
* @description Mode of the result, can influence how results are handled or returned.
|
|
364
|
+
* Mode of the result, can influence how results are handled or returned.
|
|
293
365
|
* Can be set to "all" | "onlySuccess" | "onlyError" | "onlyResponse".
|
|
294
366
|
* @default "all"
|
|
295
367
|
*/
|
|
296
368
|
resultMode?: TErrorData extends false ? "onlySuccessWithException" : TResultMode | undefined;
|
|
369
|
+
schemas?: TSchemas;
|
|
297
370
|
/**
|
|
298
371
|
* If true or the function returns true, throws errors instead of returning them
|
|
299
372
|
* The function is passed the error object and can be used to conditionally throw the error
|
|
@@ -301,23 +374,24 @@ type ExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResult
|
|
|
301
374
|
*/
|
|
302
375
|
throwOnError?: boolean | ((context: ErrorContext<TErrorData>) => boolean);
|
|
303
376
|
/**
|
|
304
|
-
*
|
|
377
|
+
* Request timeout in milliseconds
|
|
305
378
|
*/
|
|
306
379
|
timeout?: number;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
380
|
+
validators?: Validators<TData, TErrorData>;
|
|
381
|
+
} & InterceptorsOrInterceptorArray<TData, TErrorData> & Partial<InferPluginOptions<TPluginArray>> & RetryOptions<TErrorData>;
|
|
382
|
+
declare const optionsEnumToExtendFromBase: ("plugins" | "schemas" | "validators")[];
|
|
383
|
+
type CallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] = never[], TSchemas extends Schemas = DefaultMoreOptions> = ExtraOptions<TData, TErrorData, TResultMode, TPluginArray, TSchemas> & {
|
|
310
384
|
/**
|
|
311
|
-
*
|
|
385
|
+
* Options that should extend the base options.
|
|
312
386
|
*/
|
|
313
|
-
extend?: Pick<ExtraOptions<TData, TErrorData, TResultMode, TPluginArray>, (typeof optionsEnumToExtendFromBase)[number]>;
|
|
387
|
+
extend?: Pick<ExtraOptions<TData, TErrorData, TResultMode, TPluginArray, TSchemas>, (typeof optionsEnumToExtendFromBase)[number]>;
|
|
314
388
|
};
|
|
315
389
|
declare const optionsEnumToOmitFromBase: ("dedupeKey" | "extend")[];
|
|
316
|
-
type BaseCallApiExtraOptions<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBasePluginArray extends CallApiPlugin[] =
|
|
317
|
-
type CombinedCallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] =
|
|
318
|
-
type CallApiConfig<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] =
|
|
319
|
-
type BaseCallApiConfig<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBasePluginArray extends CallApiPlugin[] =
|
|
320
|
-
type CallApiParameters<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] =
|
|
390
|
+
type BaseCallApiExtraOptions<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBasePluginArray extends CallApiPlugin[] = never[], TBaseSchemas extends Schemas = DefaultMoreOptions> = Omit<CallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBasePluginArray, TBaseSchemas>, (typeof optionsEnumToOmitFromBase)[number]>;
|
|
391
|
+
type CombinedCallApiExtraOptions<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] = never[], TSchemas extends Schemas = DefaultMoreOptions> = BaseCallApiExtraOptions<TData, TErrorData, TResultMode, TPluginArray, TSchemas> & CallApiExtraOptions<TData, TErrorData, TResultMode, TPluginArray, TSchemas>;
|
|
392
|
+
type CallApiConfig<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] = never[], TSchemas extends Schemas = DefaultMoreOptions> = CallApiRequestOptions & CallApiExtraOptions<TData, TErrorData, TResultMode, TPluginArray, TSchemas>;
|
|
393
|
+
type BaseCallApiConfig<TBaseData = DefaultDataType, TBaseErrorData = DefaultDataType, TBaseResultMode extends ResultModeUnion = ResultModeUnion, TBasePluginArray extends CallApiPlugin[] = never[], TBaseSchemas extends Schemas = DefaultMoreOptions> = CallApiRequestOptions & BaseCallApiExtraOptions<TBaseData, TBaseErrorData, TBaseResultMode, TBasePluginArray, TBaseSchemas>;
|
|
394
|
+
type CallApiParameters<TData = DefaultDataType, TErrorData = DefaultDataType, TResultMode extends ResultModeUnion = ResultModeUnion, TPluginArray extends CallApiPlugin[] = never[], TSchemas extends Schemas = DefaultMoreOptions> = [initURL: string, config?: CallApiConfig<TData, TErrorData, TResultMode, TPluginArray, TSchemas>];
|
|
321
395
|
type RequestContext = UnmaskType<{
|
|
322
396
|
options: CombinedCallApiExtraOptions;
|
|
323
397
|
request: CallApiRequestOptionsForHooks;
|
|
@@ -341,7 +415,7 @@ type SuccessContext<TData> = UnmaskType<{
|
|
|
341
415
|
request: CallApiRequestOptionsForHooks;
|
|
342
416
|
response: Response;
|
|
343
417
|
}>;
|
|
344
|
-
type PossibleJavascriptErrorNames = "AbortError" | "Error" | "SyntaxError" | "TimeoutError" | "TypeError" | (`${string}Error` &
|
|
418
|
+
type PossibleJavascriptErrorNames = "AbortError" | "Error" | "SyntaxError" | "TimeoutError" | "TypeError" | (`${string}Error` & DefaultMoreOptions);
|
|
345
419
|
type PossibleJavaScriptError = UnmaskType<{
|
|
346
420
|
errorData: DOMException | Error | SyntaxError | TypeError;
|
|
347
421
|
message: string;
|
|
@@ -400,62 +474,4 @@ type ResultModeUnion = {
|
|
|
400
474
|
}[keyof ResultModeMap] | undefined;
|
|
401
475
|
type GetCallApiResult<TData, TErrorData, TResultMode> = TErrorData extends false ? ResultModeMap<TData, TErrorData>["onlySuccessWithException"] : undefined extends TResultMode ? ResultModeMap<TData, TErrorData>["all"] : TResultMode extends NonNullable<ResultModeUnion> ? ResultModeMap<TData, TErrorData>[TResultMode] : never;
|
|
402
476
|
|
|
403
|
-
type
|
|
404
|
-
(params: CallApiConfig["query"]): string | null;
|
|
405
|
-
(params: Required<CallApiConfig>["query"]): string;
|
|
406
|
-
};
|
|
407
|
-
declare const toQueryString: ToQueryStringFn;
|
|
408
|
-
declare const getResponseType: <TResponse>(response: Response, parser?: Required<CallApiExtraOptions>["responseParser"]) => {
|
|
409
|
-
arrayBuffer: () => Promise<TResponse>;
|
|
410
|
-
blob: () => Promise<TResponse>;
|
|
411
|
-
formData: () => Promise<TResponse>;
|
|
412
|
-
json: () => Promise<Record<string, unknown> | TResponse>;
|
|
413
|
-
stream: () => ReadableStream<Uint8Array<ArrayBufferLike>> | null;
|
|
414
|
-
text: () => Promise<TResponse>;
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
type UnionToIntersection<TUnion> = (TUnion extends unknown ? (param: TUnion) => void : never) extends (param: infer TParam) => void ? TParam : never;
|
|
418
|
-
type InferPluginOptions<TPluginArray extends CallApiPlugin[]> = TPluginArray extends Array<infer TPlugin extends CallApiPlugin> ? TPlugin["createExtraOptions"] extends (...params: never[]) => infer TResult ? UnionToIntersection<TResult> : NonNullable<unknown> : NonNullable<unknown>;
|
|
419
|
-
type PluginInitContext<TMoreOptions = DefaultMoreOptions> = WithMoreOptions<TMoreOptions> & {
|
|
420
|
-
initURL: string;
|
|
421
|
-
options: CombinedCallApiExtraOptions;
|
|
422
|
-
request: CallApiRequestOptionsForHooks;
|
|
423
|
-
};
|
|
424
|
-
type PluginInitResult = Partial<Omit<PluginInitContext, "request"> & {
|
|
425
|
-
request: CallApiRequestOptions;
|
|
426
|
-
}>;
|
|
427
|
-
type CallApiPlugin = {
|
|
428
|
-
/**
|
|
429
|
-
* @description Defines additional options that can be passed to callApi
|
|
430
|
-
*/
|
|
431
|
-
createExtraOptions?: (...params: never[]) => unknown;
|
|
432
|
-
/**
|
|
433
|
-
* @description A description for the plugin
|
|
434
|
-
*/
|
|
435
|
-
description?: string;
|
|
436
|
-
/**
|
|
437
|
-
* Hooks / Interceptors for the plugin
|
|
438
|
-
*/
|
|
439
|
-
hooks?: InterceptorsOrInterceptorArray;
|
|
440
|
-
/**
|
|
441
|
-
* @description A unique id for the plugin
|
|
442
|
-
*/
|
|
443
|
-
id: string;
|
|
444
|
-
/**
|
|
445
|
-
* @description A function that will be called when the plugin is
|
|
446
|
-
* initialized. This will be called before the any
|
|
447
|
-
* of the other internal functions.
|
|
448
|
-
*/
|
|
449
|
-
init?: (context: PluginInitContext) => Awaitable<PluginInitResult> | Awaitable<void>;
|
|
450
|
-
/**
|
|
451
|
-
* @description A name for the plugin
|
|
452
|
-
*/
|
|
453
|
-
name: string;
|
|
454
|
-
/**
|
|
455
|
-
* @description A version for the plugin
|
|
456
|
-
*/
|
|
457
|
-
version?: string;
|
|
458
|
-
};
|
|
459
|
-
declare const definePlugin: <TPlugin extends CallApiPlugin | AnyFunction<CallApiPlugin> = CallApiPlugin>(plugin: TPlugin) => TPlugin;
|
|
460
|
-
|
|
461
|
-
export { type BaseCallApiConfig as B, type CallApiPlugin as C, type DefaultDataType as D, type ErrorContext as E, type GetCallApiResult as G, type Interceptors as I, type PluginInitContext as P, type ResultModeUnion as R, type SuccessContext as S, type CallApiConfig as a, type BaseCallApiExtraOptions as b, type CallApiExtraOptions as c, definePlugin as d, type PossibleJavaScriptError as e, type PossibleHTTPError as f, type CallApiParameters as g, type CallApiRequestOptions as h, type CallApiRequestOptionsForHooks as i, type CallApiResultErrorVariant as j, type CallApiResultSuccessVariant as k, type CombinedCallApiExtraOptions as l, type InterceptorsOrInterceptorArray as m, type PossibleJavascriptErrorNames as n, type Register as o, type RequestContext as p, type RequestErrorContext as q, type ResponseContext as r, type ResponseErrorContext as s, toQueryString as t, defaultRetryMethods as u, defaultRetryStatusCodes as v };
|
|
477
|
+
export { type BaseCallApiConfig as B, type CallApiPlugin as C, type DefaultDataType as D, type ErrorContext as E, type GetCallApiResult as G, type InferSchemaResult as I, type PluginInitContext as P, type ResultModeUnion as R, type Schemas as S, type CallApiConfig as a, type BaseCallApiExtraOptions as b, type CallApiExtraOptions as c, definePlugin as d, type PossibleJavaScriptError as e, type PossibleHTTPError as f, type CallApiParameters as g, type CallApiRequestOptions as h, type CallApiRequestOptionsForHooks as i, type CallApiResultErrorVariant as j, type CallApiResultSuccessVariant as k, type CombinedCallApiExtraOptions as l, type Interceptors as m, type InterceptorsOrInterceptorArray as n, type PossibleJavascriptErrorNames as o, type Register as p, type RequestContext as q, type RequestErrorContext as r, type ResponseContext as s, type ResponseErrorContext as t, type SuccessContext as u, toQueryString as v, defaultRetryMethods as w, defaultRetryStatusCodes as x };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/index.ts","../../../src/error.ts","../../../src/utils/type-guards.ts","../../../src/utils/type-helpers.ts","../../../src/utils/constants.ts","../../../src/utils/common.ts"],"sourcesContent":["export { toQueryString } from \"./common\";\nexport { isHTTPError, isHTTPErrorInstance } from \"./type-guards\";\nexport { defaultRetryMethods, defaultRetryStatusCodes } from \"./constants\";\n","import type {\n\tCallApiExtraOptions,\n\tCallApiResultErrorVariant,\n\tPossibleJavascriptErrorNames,\n\tResultModeMap,\n} from \"./types\";\nimport { isHTTPErrorInstance, isObject } from \"./utils/type-guards\";\n\ntype ErrorInfo = {\n\tcloneResponse: CallApiExtraOptions[\"cloneResponse\"];\n\tdefaultErrorMessage: Required<CallApiExtraOptions>[\"defaultErrorMessage\"];\n\terror?: unknown;\n\tmessage?: string;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n};\n\nexport const resolveErrorResult = <TCallApiResult = never>(info: ErrorInfo) => {\n\tconst { cloneResponse, defaultErrorMessage, error, message: customErrorMessage, resultMode } = info;\n\n\tlet errorVariantDetails: CallApiResultErrorVariant<unknown> = {\n\t\tdata: null,\n\t\terror: {\n\t\t\terrorData: error as Error,\n\t\t\tmessage: customErrorMessage ?? (error as Error).message,\n\t\t\tname: (error as Error).name as PossibleJavascriptErrorNames,\n\t\t},\n\t\tresponse: null,\n\t};\n\n\tif (isHTTPErrorInstance(error)) {\n\t\tconst { errorData, message = defaultErrorMessage, name, response } = error;\n\n\t\terrorVariantDetails = {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\terrorData,\n\t\t\t\tmessage,\n\t\t\t\tname,\n\t\t\t},\n\t\t\tresponse: cloneResponse ? response.clone() : response,\n\t\t};\n\t}\n\n\tconst resultModeMap: ResultModeMap = {\n\t\tall: errorVariantDetails,\n\t\tonlyError: errorVariantDetails.error,\n\t\tonlyResponse: errorVariantDetails.response,\n\t\tonlySuccess: errorVariantDetails.data,\n\t\tonlySuccessWithException: errorVariantDetails.data,\n\t};\n\n\tconst getErrorResult = (customInfo?: Pick<ErrorInfo, \"message\">) => {\n\t\tconst errorResult = resultModeMap[resultMode ?? \"all\"] as TCallApiResult;\n\n\t\treturn isObject(customInfo) ? { ...errorResult, ...customInfo } : errorResult;\n\t};\n\n\treturn { errorVariantDetails, getErrorResult };\n};\n\ntype ErrorDetails<TErrorResponse> = {\n\tdefaultErrorMessage: string;\n\terrorData: TErrorResponse;\n\tresponse: Response;\n};\n\ntype ErrorOptions = {\n\tcause?: unknown;\n};\n\nexport class HTTPError<TErrorResponse = Record<string, unknown>> extends Error {\n\terrorData: ErrorDetails<TErrorResponse>[\"errorData\"];\n\tisHTTPError = true;\n\n\toverride name = \"HTTPError\" as const;\n\n\tresponse: ErrorDetails<TErrorResponse>[\"response\"];\n\n\tconstructor(errorDetails: ErrorDetails<TErrorResponse>, errorOptions?: ErrorOptions) {\n\t\tconst { defaultErrorMessage, errorData, response } = errorDetails;\n\n\t\tsuper((errorData as { message?: string } | undefined)?.message ?? defaultErrorMessage, errorOptions);\n\n\t\tthis.errorData = errorData;\n\t\tthis.response = response;\n\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n","import { HTTPError } from \"@/error\";\nimport type { PossibleHTTPError, PossibleJavaScriptError } from \"@/types\";\nimport type { AnyFunction } from \"./type-helpers\";\n\ntype ErrorObjectUnion<TErrorData = unknown> = PossibleHTTPError<TErrorData> | PossibleJavaScriptError;\n\nexport const isHTTPError = <TErrorData>(\n\terror: ErrorObjectUnion<TErrorData> | null\n): error is PossibleHTTPError<TErrorData> => {\n\treturn isPlainObject(error) && error.name === \"HTTPError\";\n};\n\nexport const isHTTPErrorInstance = <TErrorResponse>(\n\terror: unknown\n): error is HTTPError<TErrorResponse> => {\n\treturn (\n\t\t// prettier-ignore\n\t\terror instanceof HTTPError|| (isPlainObject(error) && error.name === \"HTTPError\" && error.isHTTPError === true)\n\t);\n};\n\nexport const isArray = <TArrayItem>(value: unknown): value is TArrayItem[] => Array.isArray(value);\n\nexport const isObject = (value: unknown) => typeof value === \"object\" && value !== null;\n\nexport const isPlainObject = <TPlainObject extends Record<string, unknown>>(\n\tvalue: unknown\n): value is TPlainObject => {\n\tif (!isObject(value)) {\n\t\treturn false;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value) as unknown;\n\n\t// Check if it's a plain object\n\treturn (\n\t\t// prettier-ignore\n\t\t(prototype == null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value)\n\t);\n};\n\nexport const isFunction = <TFunction extends AnyFunction>(value: unknown): value is TFunction =>\n\ttypeof value === \"function\";\n\nexport const isQueryString = (value: unknown): value is string => isString(value) && value.includes(\"=\");\n\nexport const isString = (value: unknown) => typeof value === \"string\";\n\n// https://github.com/unjs/ofetch/blob/main/src/utils.ts\n// TODO Find a way to incorporate this function in checking when to apply the bodySerializer on the body and also whether to add the content type application/json\nexport const isJSONSerializable = (value: unknown) => {\n\tif (value === undefined) {\n\t\treturn false;\n\t}\n\tconst t = typeof value;\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- No time to make this more type-safe\n\tif (t === \"string\" || t === \"number\" || t === \"boolean\" || t === null) {\n\t\treturn true;\n\t}\n\tif (t !== \"object\") {\n\t\treturn false;\n\t}\n\tif (isArray(value)) {\n\t\treturn true;\n\t}\n\tif ((value as Buffer | null)?.buffer) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Nullish coalescing makes no sense in this boolean context\n\t\t(value?.constructor && value.constructor.name === \"Object\") ||\n\t\ttypeof (value as { toJSON: () => unknown } | null)?.toJSON === \"function\"\n\t);\n};\n","// == These two types allows for adding arbitrary literal types, while still provided autocomplete for defaults.\n// == Usually intersection with \"{}\" or \"NonNullable<unknown>\" would make it work fine, but the placeholder with never type is added to make the AnyWhatever type appear last in a given union.\nexport type AnyString = string & { z_placeholder?: never };\nexport type AnyNumber = number & { z_placeholder?: never };\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is fine here\nexport type AnyObject = Record<string, any>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport type AnyFunction<TResult = any> = (...args: any[]) => TResult;\n\nexport type CallbackFn<in TParams, out TResult = void> = (...params: TParams[]) => TResult;\n\nexport type Prettify<TObject> = NonNullable<unknown> & { [Key in keyof TObject]: TObject[Key] };\n\nexport type Writeable<TObject, TType extends \"deep\" | \"shallow\" = \"shallow\"> = {\n\t-readonly [key in keyof TObject]: TType extends \"shallow\"\n\t\t? TObject[key]\n\t\t: TType extends \"deep\"\n\t\t\t? TObject[key] extends object\n\t\t\t\t? Writeable<TObject[key], TType>\n\t\t\t\t: TObject[key]\n\t\t\t: never;\n};\n\nexport const defineEnum = <const TValue>(value: TValue) => value as Prettify<Writeable<TValue, \"deep\">>;\n\n// == Using this Immediately Indexed Mapped type helper to help show computed type of anything passed to it instead of just the type name\nexport type UnmaskType<TValue> = { _: TValue }[\"_\"];\n\nexport type Awaitable<TValue> = Promise<TValue> | TValue;\n\nexport type CommonRequestHeaders =\n\t| \"Access-Control-Allow-Credentials\"\n\t| \"Access-Control-Allow-Headers\"\n\t| \"Access-Control-Allow-Methods\"\n\t| \"Access-Control-Allow-Origin\"\n\t| \"Access-Control-Expose-Headers\"\n\t| \"Access-Control-Max-Age\"\n\t| \"Age\"\n\t| \"Allow\"\n\t| \"Cache-Control\"\n\t| \"Clear-Site-Data\"\n\t| \"Content-Disposition\"\n\t| \"Content-Encoding\"\n\t| \"Content-Language\"\n\t| \"Content-Length\"\n\t| \"Content-Location\"\n\t| \"Content-Range\"\n\t| \"Content-Security-Policy-Report-Only\"\n\t| \"Content-Security-Policy\"\n\t| \"Cookie\"\n\t| \"Cross-Origin-Embedder-Policy\"\n\t| \"Cross-Origin-Opener-Policy\"\n\t| \"Cross-Origin-Resource-Policy\"\n\t| \"Date\"\n\t| \"ETag\"\n\t| \"Expires\"\n\t| \"Last-Modified\"\n\t| \"Location\"\n\t| \"Permissions-Policy\"\n\t| \"Pragma\"\n\t| \"Retry-After\"\n\t| \"Save-Data\"\n\t| \"Sec-CH-Prefers-Color-Scheme\"\n\t| \"Sec-CH-Prefers-Reduced-Motion\"\n\t| \"Sec-CH-UA-Arch\"\n\t| \"Sec-CH-UA-Bitness\"\n\t| \"Sec-CH-UA-Form-Factor\"\n\t| \"Sec-CH-UA-Full-Version-List\"\n\t| \"Sec-CH-UA-Full-Version\"\n\t| \"Sec-CH-UA-Mobile\"\n\t| \"Sec-CH-UA-Model\"\n\t| \"Sec-CH-UA-Platform-Version\"\n\t| \"Sec-CH-UA-Platform\"\n\t| \"Sec-CH-UA-WoW64\"\n\t| \"Sec-CH-UA\"\n\t| \"Sec-Fetch-Dest\"\n\t| \"Sec-Fetch-Mode\"\n\t| \"Sec-Fetch-Site\"\n\t| \"Sec-Fetch-User\"\n\t| \"Sec-GPC\"\n\t| \"Server-Timing\"\n\t| \"Server\"\n\t| \"Service-Worker-Navigation-Preload\"\n\t| \"Set-Cookie\"\n\t| \"Strict-Transport-Security\"\n\t| \"Timing-Allow-Origin\"\n\t| \"Trailer\"\n\t| \"Transfer-Encoding\"\n\t| \"Upgrade\"\n\t| \"Vary\"\n\t| \"Warning\"\n\t| \"WWW-Authenticate\"\n\t| \"X-Content-Type-Options\"\n\t| \"X-DNS-Prefetch-Control\"\n\t| \"X-Frame-Options\"\n\t| \"X-Permitted-Cross-Domain-Policies\"\n\t| \"X-Powered-By\"\n\t| \"X-Robots-Tag\"\n\t| \"X-XSS-Protection\"\n\t| AnyString;\n\nexport type CommonAuthorizationHeaders = `${\"Basic\" | \"Bearer\" | \"Token\"} ${string}`;\n\nexport type CommonContentTypes =\n\t| \"application/epub+zip\"\n\t| \"application/gzip\"\n\t| \"application/json\"\n\t| \"application/ld+json\"\n\t| \"application/octet-stream\"\n\t| \"application/ogg\"\n\t| \"application/pdf\"\n\t| \"application/rtf\"\n\t| \"application/vnd.ms-fontobject\"\n\t| \"application/wasm\"\n\t| \"application/xhtml+xml\"\n\t| \"application/xml\"\n\t| \"application/zip\"\n\t| \"audio/aac\"\n\t| \"audio/mpeg\"\n\t| \"audio/ogg\"\n\t| \"audio/opus\"\n\t| \"audio/webm\"\n\t| \"audio/x-midi\"\n\t| \"font/otf\"\n\t| \"font/ttf\"\n\t| \"font/woff\"\n\t| \"font/woff2\"\n\t| \"image/avif\"\n\t| \"image/bmp\"\n\t| \"image/gif\"\n\t| \"image/jpeg\"\n\t| \"image/png\"\n\t| \"image/svg+xml\"\n\t| \"image/tiff\"\n\t| \"image/webp\"\n\t| \"image/x-icon\"\n\t| \"model/gltf-binary\"\n\t| \"model/gltf+json\"\n\t| \"text/calendar\"\n\t| \"text/css\"\n\t| \"text/csv\"\n\t| \"text/html\"\n\t| \"text/javascript\"\n\t| \"text/plain\"\n\t| \"video/3gpp\"\n\t| \"video/3gpp2\"\n\t| \"video/av1\"\n\t| \"video/mp2t\"\n\t| \"video/mp4\"\n\t| \"video/mpeg\"\n\t| \"video/ogg\"\n\t| \"video/webm\"\n\t| \"video/x-msvideo\"\n\t| AnyString;\n","import type { BaseCallApiConfig } from \"../types\";\nimport { defineEnum } from \"./type-helpers\";\n\nexport const fetchSpecificKeys = defineEnum([\n\t\"body\",\n\t\"integrity\",\n\t\"method\",\n\t\"headers\",\n\t\"signal\",\n\t\"cache\",\n\t\"redirect\",\n\t\"window\",\n\t\"credentials\",\n\t\"keepalive\",\n\t\"referrer\",\n\t\"priority\",\n\t\"mode\",\n\t\"referrerPolicy\",\n] satisfies Array<keyof RequestInit>);\n\nconst retryStatusCodesLookup = defineEnum({\n\t408: \"Request Timeout\",\n\t409: \"Conflict\",\n\t425: \"Too Early\",\n\t429: \"Too Many Requests\",\n\t500: \"Internal Server Error\",\n\t502: \"Bad Gateway\",\n\t503: \"Service Unavailable\",\n\t504: \"Gateway Timeout\",\n});\n\nexport const defaultRetryMethods = [\"GET\", \"POST\"] satisfies BaseCallApiConfig[\"retryMethods\"];\n\n// prettier-ignore\nexport const defaultRetryStatusCodes = Object.keys(retryStatusCodesLookup).map(Number) as Required<BaseCallApiConfig>[\"retryStatusCodes\"];\n","import { getAuthHeader } from \"@/auth\";\nimport {\n\ttype BaseCallApiExtraOptions,\n\ttype CallApiConfig,\n\ttype CallApiExtraOptions,\n\ttype CallApiRequestOptions,\n\ttype ResultModeMap,\n\toptionsEnumToOmitFromBase,\n} from \"../types\";\nimport { fetchSpecificKeys } from \"./constants\";\nimport { isArray, isFunction, isPlainObject, isQueryString, isString } from \"./type-guards\";\nimport type { AnyFunction, Awaitable } from \"./type-helpers\";\n\nconst omitKeys = <TObject extends Record<string, unknown>, const TOmitArray extends Array<keyof TObject>>(\n\tinitialObject: TObject,\n\tkeysToOmit: TOmitArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToOmitSet = new Set(keysToOmit);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (!keysToOmitSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Omit<TObject, TOmitArray[number]>;\n};\n\nconst pickKeys = <TObject extends Record<string, unknown>, const TPickArray extends Array<keyof TObject>>(\n\tinitialObject: TObject,\n\tkeysToPick: TPickArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToPickSet = new Set(keysToPick);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (keysToPickSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Pick<TObject, TPickArray[number]>;\n};\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitBaseConfig = (baseConfig: Record<string, any>) =>\n\t[\n\t\tpickKeys(baseConfig, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(baseConfig, [\n\t\t\t...fetchSpecificKeys,\n\t\t\t...optionsEnumToOmitFromBase,\n\t\t]) as BaseCallApiExtraOptions,\n\t] as const;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitConfig = (config: Record<string, any>) =>\n\t[\n\t\tpickKeys(config, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(config, fetchSpecificKeys) as CallApiExtraOptions,\n\t] as const;\n\nexport const objectifyHeaders = (headers: CallApiRequestOptions[\"headers\"]) => {\n\tif (!headers || isPlainObject(headers)) {\n\t\treturn headers;\n\t}\n\n\treturn Object.fromEntries(headers);\n};\n\ntype ToQueryStringFn = {\n\t(params: CallApiConfig[\"query\"]): string | null;\n\t(params: Required<CallApiConfig>[\"query\"]): string;\n};\n\nexport const toQueryString: ToQueryStringFn = (params) => {\n\tif (!params) {\n\t\tconsole.error(\"toQueryString:\", \"No query params provided!\");\n\n\t\treturn null as never;\n\t}\n\n\treturn new URLSearchParams(params as Record<string, string>).toString();\n};\n\n// export mergeAndResolve\n\nexport const mergeAndResolveHeaders = (options: {\n\tauth: CallApiConfig[\"auth\"];\n\tbaseHeaders: CallApiConfig[\"headers\"];\n\tbody: CallApiConfig[\"body\"];\n\theaders: CallApiConfig[\"headers\"];\n}) => {\n\tconst { auth, baseHeaders, body, headers } = options;\n\n\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Nullish coalescing makes no sense in this boolean context\n\tconst shouldResolveHeaders = Boolean(baseHeaders || headers || body || auth);\n\n\t// == Return early if any of the following conditions are not met (so that native fetch would auto set the correct headers):\n\t// == - headers are provided\n\t// == - The body is an object\n\t// == - The auth option is provided\n\tif (!shouldResolveHeaders) return;\n\n\tconst headersObject: Record<string, string | undefined> = {\n\t\t...getAuthHeader(auth),\n\t\t...objectifyHeaders(baseHeaders),\n\t\t...objectifyHeaders(headers),\n\t};\n\n\tif (isQueryString(body)) {\n\t\theadersObject[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n\n\t\treturn headersObject;\n\t}\n\n\tif (isPlainObject(body) || (isString(body) && body.startsWith(\"{\"))) {\n\t\theadersObject[\"Content-Type\"] = \"application/json\";\n\t\theadersObject.Accept = \"application/json\";\n\t}\n\n\treturn headersObject;\n};\n\nexport const combineHooks = <\n\tTInterceptor extends\n\t\t| AnyFunction<Awaitable<unknown>>\n\t\t| Array<AnyFunction<Awaitable<unknown>> | undefined>,\n>(\n\tbaseInterceptor: TInterceptor | undefined,\n\tinterceptor: TInterceptor | undefined\n) => {\n\tif (isArray(baseInterceptor)) {\n\t\treturn [baseInterceptor, interceptor].flat() as TInterceptor;\n\t}\n\n\treturn interceptor ?? baseInterceptor;\n};\n\nexport const getFetchImpl = (customFetchImpl: CallApiExtraOptions[\"customFetchImpl\"]) => {\n\tif (customFetchImpl) {\n\t\treturn customFetchImpl;\n\t}\n\n\tif (typeof globalThis !== \"undefined\" && isFunction(globalThis.fetch)) {\n\t\treturn globalThis.fetch;\n\t}\n\n\tthrow new Error(\"No fetch implementation found\");\n};\n\nexport const getResponseType = <TResponse>(\n\tresponse: Response,\n\tparser?: Required<CallApiExtraOptions>[\"responseParser\"]\n) => ({\n\tarrayBuffer: () => response.arrayBuffer() as Promise<TResponse>,\n\tblob: () => response.blob() as Promise<TResponse>,\n\tformData: () => response.formData() as Promise<TResponse>,\n\tjson: async () => {\n\t\tif (parser) {\n\t\t\tconst text = await response.text();\n\t\t\treturn parser(text);\n\t\t}\n\n\t\treturn response.json() as Promise<TResponse>;\n\t},\n\tstream: () => response.body,\n\ttext: () => response.text() as Promise<TResponse>,\n});\n\nexport const executeHooks = <TInterceptor extends Awaitable<unknown>>(...interceptors: TInterceptor[]) =>\n\tPromise.all(interceptors);\n\nexport const getResponseData = async <TResponse>(\n\tresponse: Response,\n\tresponseType: keyof ReturnType<typeof getResponseType>,\n\tparser: CallApiExtraOptions[\"responseParser\"],\n\tvalidator?: CallApiExtraOptions[\"responseValidator\"]\n) => {\n\tconst RESPONSE_TYPE_LOOKUP = getResponseType<TResponse>(response, parser);\n\n\tif (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, responseType)) {\n\t\tthrow new Error(`Invalid response type: ${responseType}`);\n\t}\n\n\tconst responseData = await RESPONSE_TYPE_LOOKUP[responseType]();\n\n\tconst validResponseData = validator ? validator(responseData) : responseData;\n\n\treturn validResponseData;\n};\n\ntype SuccessInfo = {\n\tdata: unknown;\n\tresponse: Response;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n};\n\n// == The CallApiResult type is used to cast all return statements due to a design limitation in ts.\n// LINK - See https://www.zhenghao.io/posts/type-functions for more info\nexport const resolveSuccessResult = <TCallApiResult>(info: SuccessInfo): TCallApiResult => {\n\tconst { data, response, resultMode } = info;\n\n\tconst apiDetails = { data, error: null, response };\n\n\tif (!resultMode) {\n\t\treturn apiDetails as TCallApiResult;\n\t}\n\n\tconst resultModeMap: ResultModeMap = {\n\t\tall: apiDetails,\n\t\tonlyError: apiDetails.error,\n\t\tonlyResponse: apiDetails.response,\n\t\tonlySuccess: apiDetails.data,\n\t\tonlySuccessWithException: apiDetails.data,\n\t};\n\n\treturn resultModeMap[resultMode] as TCallApiResult;\n};\n\nconst PromiseWithResolvers = () => {\n\tlet reject!: (reason?: unknown) => void;\n\tlet resolve!: (value: unknown) => void;\n\n\tconst promise = new Promise((res, rej) => {\n\t\tresolve = res;\n\t\treject = rej;\n\t});\n\n\treturn { promise, reject, resolve };\n};\n\nexport const waitUntil = (delay: number) => {\n\tif (delay === 0) return;\n\n\tconst { promise, resolve } = PromiseWithResolvers();\n\n\tsetTimeout(resolve, delay);\n\n\treturn promise;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsEO,IAAM,YAAN,cAAkE,MAAM;AAAA,EAC9E;AAAA,EACA,cAAc;AAAA,EAEL,OAAO;AAAA,EAEhB;AAAA,EAEA,YAAY,cAA4C,cAA6B;AACpF,UAAM,EAAE,qBAAqB,WAAW,SAAS,IAAI;AAErD,UAAO,WAAgD,WAAW,qBAAqB,YAAY;AAEnG,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,EAC/C;AACD;;;AClFO,IAAM,cAAc,CAC1B,UAC4C;AAC5C,SAAO,cAAc,KAAK,KAAK,MAAM,SAAS;AAC/C;AAEO,IAAM,sBAAsB,CAClC,UACwC;AACxC;AAAA;AAAA,IAEC,iBAAiB,aAAa,cAAc,KAAK,KAAK,MAAM,SAAS,eAAe,MAAM,gBAAgB;AAAA;AAE5G;AAIO,IAAM,WAAW,CAAC,UAAmB,OAAO,UAAU,YAAY,UAAU;AAE5E,IAAM,gBAAgB,CAC5B,UAC2B;AAC3B,MAAI,CAAC,SAAS,KAAK,GAAG;AACrB,WAAO;AAAA,EACR;AAEA,QAAM,YAAY,OAAO,eAAe,KAAK;AAG7C;AAAA;AAAA,KAEE,aAAa,QAAQ,cAAc,OAAO,aAAa,OAAO,eAAe,SAAS,MAAM,SAAS,EAAE,OAAO,eAAe;AAAA;AAEhI;;;ACdO,IAAM,aAAa,CAAe,UAAkB;;;ACtBpD,IAAM,oBAAoB,WAAW;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAoC;AAEpC,IAAM,yBAAyB,WAAW;AAAA,EACzC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN,CAAC;AAEM,IAAM,sBAAsB,CAAC,OAAO,MAAM;AAG1C,IAAM,0BAA0B,OAAO,KAAK,sBAAsB,EAAE,IAAI,MAAM;;;AC2C9E,IAAM,gBAAiC,CAAC,WAAW;AACzD,MAAI,CAAC,QAAQ;AACZ,YAAQ,MAAM,kBAAkB,2BAA2B;AAE3D,WAAO;AAAA,EACR;AAEA,SAAO,IAAI,gBAAgB,MAAgC,EAAE,SAAS;AACvE;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/index.ts","../../../src/error.ts","../../../src/utils/type-guards.ts","../../../src/utils/type-helpers.ts","../../../src/utils/constants.ts","../../../src/utils/common.ts"],"sourcesContent":["export { toQueryString } from \"./common\";\nexport { isHTTPError, isHTTPErrorInstance } from \"./type-guards\";\nexport { defaultRetryMethods, defaultRetryStatusCodes } from \"./constants\";\n","import type {\n\tCallApiExtraOptions,\n\tCallApiResultErrorVariant,\n\tPossibleJavascriptErrorNames,\n\tResultModeMap,\n} from \"./types\";\nimport { isHTTPErrorInstance, isObject } from \"./utils/type-guards\";\n\ntype ErrorInfo = {\n\tcloneResponse: CallApiExtraOptions[\"cloneResponse\"];\n\tdefaultErrorMessage: Required<CallApiExtraOptions>[\"defaultErrorMessage\"];\n\terror?: unknown;\n\tmessage?: string;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n};\n\nexport const resolveErrorResult = <TCallApiResult = never>(info: ErrorInfo) => {\n\tconst { cloneResponse, defaultErrorMessage, error, message: customErrorMessage, resultMode } = info;\n\n\tlet errorVariantDetails: CallApiResultErrorVariant<unknown> = {\n\t\tdata: null,\n\t\terror: {\n\t\t\terrorData: error as Error,\n\t\t\tmessage: customErrorMessage ?? (error as Error).message,\n\t\t\tname: (error as Error).name as PossibleJavascriptErrorNames,\n\t\t},\n\t\tresponse: null,\n\t};\n\n\tif (isHTTPErrorInstance(error)) {\n\t\tconst { errorData, message = defaultErrorMessage, name, response } = error;\n\n\t\terrorVariantDetails = {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\terrorData,\n\t\t\t\tmessage,\n\t\t\t\tname,\n\t\t\t},\n\t\t\tresponse: cloneResponse ? response.clone() : response,\n\t\t};\n\t}\n\n\tconst resultModeMap: ResultModeMap = {\n\t\tall: errorVariantDetails,\n\t\tonlyError: errorVariantDetails.error,\n\t\tonlyResponse: errorVariantDetails.response,\n\t\tonlySuccess: errorVariantDetails.data,\n\t\tonlySuccessWithException: errorVariantDetails.data,\n\t};\n\n\tconst getErrorResult = (customInfo?: Pick<ErrorInfo, \"message\">) => {\n\t\tconst errorResult = resultModeMap[resultMode ?? \"all\"] as TCallApiResult;\n\n\t\treturn isObject(customInfo) ? { ...errorResult, ...customInfo } : errorResult;\n\t};\n\n\treturn { errorVariantDetails, getErrorResult };\n};\n\ntype ErrorDetails<TErrorResponse> = {\n\tdefaultErrorMessage: string;\n\terrorData: TErrorResponse;\n\tresponse: Response;\n};\n\ntype ErrorOptions = {\n\tcause?: unknown;\n};\n\nexport class HTTPError<TErrorResponse = Record<string, unknown>> extends Error {\n\terrorData: ErrorDetails<TErrorResponse>[\"errorData\"];\n\tisHTTPError = true;\n\n\toverride name = \"HTTPError\" as const;\n\n\tresponse: ErrorDetails<TErrorResponse>[\"response\"];\n\n\tconstructor(errorDetails: ErrorDetails<TErrorResponse>, errorOptions?: ErrorOptions) {\n\t\tconst { defaultErrorMessage, errorData, response } = errorDetails;\n\n\t\tsuper((errorData as { message?: string } | undefined)?.message ?? defaultErrorMessage, errorOptions);\n\n\t\tthis.errorData = errorData;\n\t\tthis.response = response;\n\n\t\tError.captureStackTrace(this, this.constructor);\n\t}\n}\n","import { HTTPError } from \"@/error\";\nimport type { PossibleHTTPError, PossibleJavaScriptError } from \"@/types\";\nimport type { AnyFunction } from \"./type-helpers\";\n\ntype ErrorObjectUnion<TErrorData = unknown> = PossibleHTTPError<TErrorData> | PossibleJavaScriptError;\n\nexport const isHTTPError = <TErrorData>(\n\terror: ErrorObjectUnion<TErrorData> | null\n): error is PossibleHTTPError<TErrorData> => {\n\treturn isPlainObject(error) && error.name === \"HTTPError\";\n};\n\nexport const isHTTPErrorInstance = <TErrorResponse>(\n\terror: unknown\n): error is HTTPError<TErrorResponse> => {\n\treturn (\n\t\t// prettier-ignore\n\t\terror instanceof HTTPError|| (isPlainObject(error) && error.name === \"HTTPError\" && error.isHTTPError === true)\n\t);\n};\n\nexport const isArray = <TArrayItem>(value: unknown): value is TArrayItem[] => Array.isArray(value);\n\nexport const isObject = (value: unknown) => typeof value === \"object\" && value !== null;\n\nexport const isPlainObject = <TPlainObject extends Record<string, unknown>>(\n\tvalue: unknown\n): value is TPlainObject => {\n\tif (!isObject(value)) {\n\t\treturn false;\n\t}\n\n\tconst prototype = Object.getPrototypeOf(value) as unknown;\n\n\t// Check if it's a plain object\n\treturn (\n\t\t// prettier-ignore\n\t\t(prototype == null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value)\n\t);\n};\n\nexport const isFunction = <TFunction extends AnyFunction>(value: unknown): value is TFunction =>\n\ttypeof value === \"function\";\n\nexport const isQueryString = (value: unknown): value is string => isString(value) && value.includes(\"=\");\n\nexport const isString = (value: unknown) => typeof value === \"string\";\n\n// https://github.com/unjs/ofetch/blob/main/src/utils.ts\n// TODO Find a way to incorporate this function in checking when to apply the bodySerializer on the body and also whether to add the content type application/json\nexport const isJSONSerializable = (value: unknown) => {\n\tif (value === undefined) {\n\t\treturn false;\n\t}\n\tconst t = typeof value;\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- No time to make this more type-safe\n\tif (t === \"string\" || t === \"number\" || t === \"boolean\" || t === null) {\n\t\treturn true;\n\t}\n\tif (t !== \"object\") {\n\t\treturn false;\n\t}\n\tif (isArray(value)) {\n\t\treturn true;\n\t}\n\tif ((value as Buffer | null)?.buffer) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Nullish coalescing makes no sense in this boolean context\n\t\t(value?.constructor && value.constructor.name === \"Object\") ||\n\t\ttypeof (value as { toJSON: () => unknown } | null)?.toJSON === \"function\"\n\t);\n};\n","// == These two types allows for adding arbitrary literal types, while still provided autocomplete for defaults.\n// == Usually intersection with \"{}\" or \"NonNullable<unknown>\" would make it work fine, but the placeholder with never type is added to make the AnyWhatever type appear last in a given union.\nexport type AnyString = string & { z_placeholder?: never };\nexport type AnyNumber = number & { z_placeholder?: never };\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is fine here\nexport type AnyObject = Record<string, any>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport type AnyFunction<TResult = any> = (...args: any[]) => TResult;\n\nexport type CallbackFn<in TParams, out TResult = void> = (...params: TParams[]) => TResult;\n\nexport type Prettify<TObject> = NonNullable<unknown> & { [Key in keyof TObject]: TObject[Key] };\n\nexport type Writeable<TObject, TType extends \"deep\" | \"shallow\" = \"shallow\"> = {\n\t-readonly [key in keyof TObject]: TType extends \"shallow\"\n\t\t? TObject[key]\n\t\t: TType extends \"deep\"\n\t\t\t? TObject[key] extends object\n\t\t\t\t? Writeable<TObject[key], TType>\n\t\t\t\t: TObject[key]\n\t\t\t: never;\n};\n\nexport const defineEnum = <const TValue>(value: TValue) => value as Prettify<Writeable<TValue, \"deep\">>;\n\n// == Using this Immediately Indexed Mapped type helper to help show computed type of anything passed to it instead of just the type name\nexport type UnmaskType<TValue> = { _: TValue }[\"_\"];\n\nexport type Awaitable<TValue> = Promise<TValue> | TValue;\n\nexport type CommonRequestHeaders =\n\t| \"Access-Control-Allow-Credentials\"\n\t| \"Access-Control-Allow-Headers\"\n\t| \"Access-Control-Allow-Methods\"\n\t| \"Access-Control-Allow-Origin\"\n\t| \"Access-Control-Expose-Headers\"\n\t| \"Access-Control-Max-Age\"\n\t| \"Age\"\n\t| \"Allow\"\n\t| \"Cache-Control\"\n\t| \"Clear-Site-Data\"\n\t| \"Content-Disposition\"\n\t| \"Content-Encoding\"\n\t| \"Content-Language\"\n\t| \"Content-Length\"\n\t| \"Content-Location\"\n\t| \"Content-Range\"\n\t| \"Content-Security-Policy-Report-Only\"\n\t| \"Content-Security-Policy\"\n\t| \"Cookie\"\n\t| \"Cross-Origin-Embedder-Policy\"\n\t| \"Cross-Origin-Opener-Policy\"\n\t| \"Cross-Origin-Resource-Policy\"\n\t| \"Date\"\n\t| \"ETag\"\n\t| \"Expires\"\n\t| \"Last-Modified\"\n\t| \"Location\"\n\t| \"Permissions-Policy\"\n\t| \"Pragma\"\n\t| \"Retry-After\"\n\t| \"Save-Data\"\n\t| \"Sec-CH-Prefers-Color-Scheme\"\n\t| \"Sec-CH-Prefers-Reduced-Motion\"\n\t| \"Sec-CH-UA-Arch\"\n\t| \"Sec-CH-UA-Bitness\"\n\t| \"Sec-CH-UA-Form-Factor\"\n\t| \"Sec-CH-UA-Full-Version-List\"\n\t| \"Sec-CH-UA-Full-Version\"\n\t| \"Sec-CH-UA-Mobile\"\n\t| \"Sec-CH-UA-Model\"\n\t| \"Sec-CH-UA-Platform-Version\"\n\t| \"Sec-CH-UA-Platform\"\n\t| \"Sec-CH-UA-WoW64\"\n\t| \"Sec-CH-UA\"\n\t| \"Sec-Fetch-Dest\"\n\t| \"Sec-Fetch-Mode\"\n\t| \"Sec-Fetch-Site\"\n\t| \"Sec-Fetch-User\"\n\t| \"Sec-GPC\"\n\t| \"Server-Timing\"\n\t| \"Server\"\n\t| \"Service-Worker-Navigation-Preload\"\n\t| \"Set-Cookie\"\n\t| \"Strict-Transport-Security\"\n\t| \"Timing-Allow-Origin\"\n\t| \"Trailer\"\n\t| \"Transfer-Encoding\"\n\t| \"Upgrade\"\n\t| \"Vary\"\n\t| \"Warning\"\n\t| \"WWW-Authenticate\"\n\t| \"X-Content-Type-Options\"\n\t| \"X-DNS-Prefetch-Control\"\n\t| \"X-Frame-Options\"\n\t| \"X-Permitted-Cross-Domain-Policies\"\n\t| \"X-Powered-By\"\n\t| \"X-Robots-Tag\"\n\t| \"X-XSS-Protection\"\n\t| AnyString;\n\nexport type CommonAuthorizationHeaders = `${\"Basic\" | \"Bearer\" | \"Token\"} ${string}`;\n\nexport type CommonContentTypes =\n\t| \"application/epub+zip\"\n\t| \"application/gzip\"\n\t| \"application/json\"\n\t| \"application/ld+json\"\n\t| \"application/octet-stream\"\n\t| \"application/ogg\"\n\t| \"application/pdf\"\n\t| \"application/rtf\"\n\t| \"application/vnd.ms-fontobject\"\n\t| \"application/wasm\"\n\t| \"application/xhtml+xml\"\n\t| \"application/xml\"\n\t| \"application/zip\"\n\t| \"audio/aac\"\n\t| \"audio/mpeg\"\n\t| \"audio/ogg\"\n\t| \"audio/opus\"\n\t| \"audio/webm\"\n\t| \"audio/x-midi\"\n\t| \"font/otf\"\n\t| \"font/ttf\"\n\t| \"font/woff\"\n\t| \"font/woff2\"\n\t| \"image/avif\"\n\t| \"image/bmp\"\n\t| \"image/gif\"\n\t| \"image/jpeg\"\n\t| \"image/png\"\n\t| \"image/svg+xml\"\n\t| \"image/tiff\"\n\t| \"image/webp\"\n\t| \"image/x-icon\"\n\t| \"model/gltf-binary\"\n\t| \"model/gltf+json\"\n\t| \"text/calendar\"\n\t| \"text/css\"\n\t| \"text/csv\"\n\t| \"text/html\"\n\t| \"text/javascript\"\n\t| \"text/plain\"\n\t| \"video/3gpp\"\n\t| \"video/3gpp2\"\n\t| \"video/av1\"\n\t| \"video/mp2t\"\n\t| \"video/mp4\"\n\t| \"video/mpeg\"\n\t| \"video/ogg\"\n\t| \"video/webm\"\n\t| \"video/x-msvideo\"\n\t| AnyString;\n","import type { BaseCallApiConfig } from \"../types\";\nimport { defineEnum } from \"./type-helpers\";\n\nexport const fetchSpecificKeys = defineEnum([\n\t\"body\",\n\t\"integrity\",\n\t\"method\",\n\t\"headers\",\n\t\"signal\",\n\t\"cache\",\n\t\"redirect\",\n\t\"window\",\n\t\"credentials\",\n\t\"keepalive\",\n\t\"referrer\",\n\t\"priority\",\n\t\"mode\",\n\t\"referrerPolicy\",\n] satisfies Array<keyof RequestInit>);\n\nconst retryStatusCodesLookup = defineEnum({\n\t408: \"Request Timeout\",\n\t409: \"Conflict\",\n\t425: \"Too Early\",\n\t429: \"Too Many Requests\",\n\t500: \"Internal Server Error\",\n\t502: \"Bad Gateway\",\n\t503: \"Service Unavailable\",\n\t504: \"Gateway Timeout\",\n});\n\nexport const defaultRetryMethods = [\"GET\", \"POST\"] satisfies BaseCallApiConfig[\"retryMethods\"];\n\n// prettier-ignore\nexport const defaultRetryStatusCodes = Object.keys(retryStatusCodesLookup).map(Number) as Required<BaseCallApiConfig>[\"retryStatusCodes\"];\n","import { getAuthHeader } from \"@/auth\";\nimport { type Schemas, type Validators, standardSchemaParser } from \"@/validation\";\nimport {\n\ttype BaseCallApiExtraOptions,\n\ttype CallApiConfig,\n\ttype CallApiExtraOptions,\n\ttype CallApiRequestOptions,\n\ttype ResultModeMap,\n\toptionsEnumToOmitFromBase,\n} from \"../types\";\nimport { fetchSpecificKeys } from \"./constants\";\nimport { isArray, isFunction, isPlainObject, isQueryString, isString } from \"./type-guards\";\nimport type { AnyFunction, Awaitable } from \"./type-helpers\";\n\nconst omitKeys = <TObject extends Record<string, unknown>, const TOmitArray extends Array<keyof TObject>>(\n\tinitialObject: TObject,\n\tkeysToOmit: TOmitArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToOmitSet = new Set(keysToOmit);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (!keysToOmitSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Omit<TObject, TOmitArray[number]>;\n};\n\nconst pickKeys = <TObject extends Record<string, unknown>, const TPickArray extends Array<keyof TObject>>(\n\tinitialObject: TObject,\n\tkeysToPick: TPickArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToPickSet = new Set(keysToPick);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (keysToPickSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Pick<TObject, TPickArray[number]>;\n};\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitBaseConfig = (baseConfig: Record<string, any>) =>\n\t[\n\t\tpickKeys(baseConfig, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(baseConfig, [\n\t\t\t...fetchSpecificKeys,\n\t\t\t...optionsEnumToOmitFromBase,\n\t\t]) as BaseCallApiExtraOptions,\n\t] as const;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitConfig = (config: Record<string, any>) =>\n\t[\n\t\tpickKeys(config, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(config, fetchSpecificKeys) as CallApiExtraOptions,\n\t] as const;\n\nexport const objectifyHeaders = (headers: CallApiRequestOptions[\"headers\"]) => {\n\tif (!headers || isPlainObject(headers)) {\n\t\treturn headers;\n\t}\n\n\treturn Object.fromEntries(headers);\n};\n\ntype ToQueryStringFn = {\n\t(params: CallApiConfig[\"query\"]): string | null;\n\t(params: Required<CallApiConfig>[\"query\"]): string;\n};\n\nexport const toQueryString: ToQueryStringFn = (params) => {\n\tif (!params) {\n\t\tconsole.error(\"toQueryString:\", \"No query params provided!\");\n\n\t\treturn null as never;\n\t}\n\n\treturn new URLSearchParams(params as Record<string, string>).toString();\n};\n\n// export mergeAndResolve\n\nexport const mergeAndResolveHeaders = (options: {\n\tauth: CallApiConfig[\"auth\"];\n\tbaseHeaders: CallApiConfig[\"headers\"];\n\tbody: CallApiConfig[\"body\"];\n\theaders: CallApiConfig[\"headers\"];\n}) => {\n\tconst { auth, baseHeaders, body, headers } = options;\n\n\t// eslint-disable-next-line ts-eslint/prefer-nullish-coalescing -- Nullish coalescing makes no sense in this boolean context\n\tconst shouldResolveHeaders = Boolean(baseHeaders || headers || body || auth);\n\n\t// == Return early if any of the following conditions are not met (so that native fetch would auto set the correct headers):\n\t// == - headers are provided\n\t// == - The body is an object\n\t// == - The auth option is provided\n\tif (!shouldResolveHeaders) return;\n\n\tconst headersObject: Record<string, string | undefined> = {\n\t\t...getAuthHeader(auth),\n\t\t...objectifyHeaders(baseHeaders),\n\t\t...objectifyHeaders(headers),\n\t};\n\n\tif (isQueryString(body)) {\n\t\theadersObject[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n\n\t\treturn headersObject;\n\t}\n\n\tif (isPlainObject(body) || (isString(body) && body.startsWith(\"{\"))) {\n\t\theadersObject[\"Content-Type\"] = \"application/json\";\n\t\theadersObject.Accept = \"application/json\";\n\t}\n\n\treturn headersObject;\n};\n\nexport const combineHooks = <\n\tTInterceptor extends\n\t\t| AnyFunction<Awaitable<unknown>>\n\t\t| Array<AnyFunction<Awaitable<unknown>> | undefined>,\n>(\n\tbaseInterceptor: TInterceptor | undefined,\n\tinterceptor: TInterceptor | undefined\n) => {\n\tif (isArray(baseInterceptor)) {\n\t\treturn [baseInterceptor, interceptor].flat() as TInterceptor;\n\t}\n\n\treturn interceptor ?? baseInterceptor;\n};\n\nexport const getFetchImpl = (customFetchImpl: CallApiExtraOptions[\"customFetchImpl\"]) => {\n\tif (customFetchImpl) {\n\t\treturn customFetchImpl;\n\t}\n\n\tif (typeof globalThis !== \"undefined\" && isFunction(globalThis.fetch)) {\n\t\treturn globalThis.fetch;\n\t}\n\n\tthrow new Error(\"No fetch implementation found\");\n};\n\nexport const getResponseType = <TResponse>(\n\tresponse: Response,\n\tparser?: Required<CallApiExtraOptions>[\"responseParser\"]\n) => ({\n\tarrayBuffer: () => response.arrayBuffer() as Promise<TResponse>,\n\tblob: () => response.blob() as Promise<TResponse>,\n\tformData: () => response.formData() as Promise<TResponse>,\n\tjson: async () => {\n\t\tif (parser) {\n\t\t\tconst text = await response.text();\n\t\t\treturn parser(text);\n\t\t}\n\n\t\treturn response.json() as Promise<TResponse>;\n\t},\n\tstream: () => response.body,\n\ttext: () => response.text() as Promise<TResponse>,\n});\n\nexport const executeHooks = <TInterceptor extends Awaitable<unknown>>(...interceptors: TInterceptor[]) =>\n\tPromise.all(interceptors);\n\nexport const getResponseData = async <TResponse>(\n\tresponse: Response,\n\tresponseType: keyof ReturnType<typeof getResponseType>,\n\tparser: CallApiExtraOptions[\"responseParser\"],\n\tschema?: NonNullable<Schemas>[keyof NonNullable<Schemas>],\n\tvalidator?: NonNullable<Validators>[keyof NonNullable<Validators>]\n) => {\n\tconst RESPONSE_TYPE_LOOKUP = getResponseType<TResponse>(response, parser);\n\n\tif (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, responseType)) {\n\t\tthrow new Error(`Invalid response type: ${responseType}`);\n\t}\n\n\tconst responseData = await RESPONSE_TYPE_LOOKUP[responseType]();\n\n\tconst validResponseData = validator ? validator(responseData) : responseData;\n\n\tconst schemaValidResponseData = schema\n\t\t? await standardSchemaParser(schema, validResponseData)\n\t\t: validResponseData;\n\n\treturn schemaValidResponseData;\n};\n\ntype SuccessInfo = {\n\tdata: unknown;\n\tresponse: Response;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n};\n\n// == The CallApiResult type is used to cast all return statements due to a design limitation in ts.\n// LINK - See https://www.zhenghao.io/posts/type-functions for more info\nexport const resolveSuccessResult = <TCallApiResult>(info: SuccessInfo): TCallApiResult => {\n\tconst { data, response, resultMode } = info;\n\n\tconst apiDetails = { data, error: null, response };\n\n\tif (!resultMode) {\n\t\treturn apiDetails as TCallApiResult;\n\t}\n\n\tconst resultModeMap: ResultModeMap = {\n\t\tall: apiDetails,\n\t\tonlyError: apiDetails.error,\n\t\tonlyResponse: apiDetails.response,\n\t\tonlySuccess: apiDetails.data,\n\t\tonlySuccessWithException: apiDetails.data,\n\t};\n\n\treturn resultModeMap[resultMode] as TCallApiResult;\n};\n\nconst PromiseWithResolvers = () => {\n\tlet reject!: (reason?: unknown) => void;\n\tlet resolve!: (value: unknown) => void;\n\n\tconst promise = new Promise((res, rej) => {\n\t\tresolve = res;\n\t\treject = rej;\n\t});\n\n\treturn { promise, reject, resolve };\n};\n\nexport const waitUntil = (delay: number) => {\n\tif (delay === 0) return;\n\n\tconst { promise, resolve } = PromiseWithResolvers();\n\n\tsetTimeout(resolve, delay);\n\n\treturn promise;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsEO,IAAM,YAAN,cAAkE,MAAM;AAAA,EAC9E;AAAA,EACA,cAAc;AAAA,EAEL,OAAO;AAAA,EAEhB;AAAA,EAEA,YAAY,cAA4C,cAA6B;AACpF,UAAM,EAAE,qBAAqB,WAAW,SAAS,IAAI;AAErD,UAAO,WAAgD,WAAW,qBAAqB,YAAY;AAEnG,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,UAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,EAC/C;AACD;;;AClFO,IAAM,cAAc,CAC1B,UAC4C;AAC5C,SAAO,cAAc,KAAK,KAAK,MAAM,SAAS;AAC/C;AAEO,IAAM,sBAAsB,CAClC,UACwC;AACxC;AAAA;AAAA,IAEC,iBAAiB,aAAa,cAAc,KAAK,KAAK,MAAM,SAAS,eAAe,MAAM,gBAAgB;AAAA;AAE5G;AAIO,IAAM,WAAW,CAAC,UAAmB,OAAO,UAAU,YAAY,UAAU;AAE5E,IAAM,gBAAgB,CAC5B,UAC2B;AAC3B,MAAI,CAAC,SAAS,KAAK,GAAG;AACrB,WAAO;AAAA,EACR;AAEA,QAAM,YAAY,OAAO,eAAe,KAAK;AAG7C;AAAA;AAAA,KAEE,aAAa,QAAQ,cAAc,OAAO,aAAa,OAAO,eAAe,SAAS,MAAM,SAAS,EAAE,OAAO,eAAe;AAAA;AAEhI;;;ACdO,IAAM,aAAa,CAAe,UAAkB;;;ACtBpD,IAAM,oBAAoB,WAAW;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAoC;AAEpC,IAAM,yBAAyB,WAAW;AAAA,EACzC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN,CAAC;AAEM,IAAM,sBAAsB,CAAC,OAAO,MAAM;AAG1C,IAAM,0BAA0B,OAAO,KAAK,sBAAsB,EAAE,IAAI,MAAM;;;AC4C9E,IAAM,gBAAiC,CAAC,WAAW;AACzD,MAAI,CAAC,QAAQ;AACZ,YAAQ,MAAM,kBAAkB,2BAA2B;AAE3D,WAAO;AAAA,EACR;AAEA,SAAO,IAAI,gBAAgB,MAAgC,EAAE,SAAS;AACvE;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { f as PossibleHTTPError, e as PossibleJavaScriptError } from '../
|
|
2
|
-
export {
|
|
1
|
+
import { f as PossibleHTTPError, e as PossibleJavaScriptError } from '../types-CNYLI9wS.cjs';
|
|
2
|
+
export { w as defaultRetryMethods, x as defaultRetryStatusCodes, v as toQueryString } from '../types-CNYLI9wS.cjs';
|
|
3
3
|
import { H as HTTPError } from '../error-lBRMiMeF.cjs';
|
|
4
|
+
import '@standard-schema/spec';
|
|
4
5
|
|
|
5
6
|
type ErrorObjectUnion<TErrorData = unknown> = PossibleHTTPError<TErrorData> | PossibleJavaScriptError;
|
|
6
7
|
declare const isHTTPError: <TErrorData>(error: ErrorObjectUnion<TErrorData> | null) => error is PossibleHTTPError<TErrorData>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=e=>{const{cloneResponse:r,defaultErrorMessage:t,error:s,message:a,resultMode:i}=e;let l={data:null,error:{errorData:s,message:a??s.message,name:s.name},response:null};if(o(s)){const{errorData:e,message:o=t,name:n,response:a}=s;l={data:null,error:{errorData:e,message:o,name:n},response:r?a.clone():a}}const c={all:l,onlyError:l.error,onlyResponse:l.response,onlySuccess:l.data,onlySuccessWithException:l.data};return{errorVariantDetails:l,getErrorResult:e=>{const r=c[i??"all"];return n(e)?{...r,...e}:r}}},r=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,Error.captureStackTrace(this,this.constructor)}},t=e=>a(e)&&"HTTPError"===e.name,o=e=>e instanceof r||a(e)&&"HTTPError"===e.name&&!0===e.isHTTPError,s=e=>Array.isArray(e),n=e=>"object"==typeof e&&null!==e,a=e=>{if(!n(e))return!1;const r=Object.getPrototypeOf(e);return(null==r||r===Object.prototype||null===Object.getPrototypeOf(r))&&!(Symbol.toStringTag in e)},i=e=>"function"==typeof e,l=e=>"string"==typeof e,c=e=>i(e)?e():e,u=e=>{if(void 0!==e){if(l(e)||null===e)return{Authorization:`Bearer ${e}`};switch(e.type){case"Basic":{const r=c(e.username),t=c(e.password);if(void 0===r||void 0===t)return;return{Authorization:`Basic ${globalThis.btoa(`${r}:${t}`)}`}}case"Custom":{const r=c(e.value);if(void 0===r)return;return{Authorization:`${c(e.prefix)} ${r}`}}default:{const r=c(e.bearer),t=c(e.token);return"token"in e&&void 0!==t?{Authorization:`Token ${t}`}:void 0!==r&&{Authorization:`Bearer ${r}`}}}}},d=e=>({schemas:e.schemas?{...e.schemas,...e.extend?.schemas}:void 0,validators:e.validators?{...e.validators,...e.extend?.validators}:void 0}),p=["extend","dedupeKey"],f=["body","integrity","method","headers","signal","cache","redirect","window","credentials","keepalive","referrer","priority","mode","referrerPolicy"],y={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","POST"],h=Object.keys(y).map(Number),b=(e,r)=>{const t={},o=new Set(r);for(const[r,s]of Object.entries(e))o.has(r)||(t[r]=s);return t},T=(e,r)=>{const t={},o=new Set(r);for(const[r,s]of Object.entries(e))o.has(r)&&(t[r]=s);return t},v=e=>[T(e,f),b(e,[...f,...p])],w=e=>[T(e,f),b(e,f)],g=e=>!e||a(e)?e:Object.fromEntries(e),E=e=>e?new URLSearchParams(e).toString():(console.error("toQueryString:","No query params provided!"),null),S=e=>{const{auth:r,baseHeaders:t,body:o,headers:s}=e;if(!Boolean(t||s||o||r))return;const n={...u(r),...g(t),...g(s)};return l(i=o)&&i.includes("=")?(n["Content-Type"]="application/x-www-form-urlencoded",n):((a(o)||l(o)&&o.startsWith("{"))&&(n["Content-Type"]="application/json",n.Accept="application/json"),n);var i},j=(e,r)=>s(e)?[e,r].flat():r??e,O=e=>{if(e)return e;if("undefined"!=typeof globalThis&&i(globalThis.fetch))return globalThis.fetch;throw new Error("No fetch implementation found")},x=(...e)=>Promise.all(e),P=async(e,r,t,o,s)=>{const n=((e,r)=>({arrayBuffer:()=>e.arrayBuffer(),blob:()=>e.blob(),formData:()=>e.formData(),json:async()=>{if(r){const t=await e.text();return r(t)}return e.json()},stream:()=>e.body,text:()=>e.text()}))(e,t);if(!Object.hasOwn(n,r))throw new Error(`Invalid response type: ${r}`);const a=await n[r](),i=s?s(a):a,l=o?await(async(e,r)=>{const t=await e["~standard"].validate(r);if(t.issues)throw new Error(JSON.stringify(t.issues,null,2));return t.value})(o,i):i;return l},D=e=>{const{data:r,response:t,resultMode:o}=e,s={data:r,error:null,response:t};if(!o)return s;return{all:s,onlyError:s.error,onlyResponse:s.response,onlySuccess:s.data,onlySuccessWithException:s.data}[o]},$=e=>{if(0===e)return;const{promise:r,resolve:t}=(()=>{let e,r;return{promise:new Promise(((t,o)=>{r=t,e=o})),reject:e,resolve:r}})();return setTimeout(t,e),r};export{r as HTTPError,j as combineHooks,d as createExtensibleSchemasAndValidators,m as defaultRetryMethods,h as defaultRetryStatusCodes,x as executeHooks,O as getFetchImpl,P as getResponseData,s as isArray,i as isFunction,t as isHTTPError,o as isHTTPErrorInstance,a as isPlainObject,l as isString,S as mergeAndResolveHeaders,e as resolveErrorResult,D as resolveSuccessResult,v as splitBaseConfig,w as splitConfig,E as toQueryString,$ as waitUntil};//# sourceMappingURL=chunk-KABMV5OF.js.map
|