@zayne-labs/callapi 1.6.14 → 1.6.15
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 +1 -1
- package/dist/cjs/{common-B_9jiZXC.d.cts → error-MH9dJCiM.d.cts} +25 -9
- package/dist/cjs/index.cjs +773 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +11 -10
- package/dist/cjs/utils/index.cjs +129 -1
- package/dist/cjs/utils/index.cjs.map +1 -1
- package/dist/cjs/utils/index.d.cts +2 -3
- package/dist/esm/chunk-JP7YMR7V.js +263 -0
- package/dist/esm/{chunk-MOMG57MZ.js.map → chunk-JP7YMR7V.js.map} +1 -1
- package/dist/esm/{common-B_9jiZXC.d.ts → error-MH9dJCiM.d.ts} +25 -9
- package/dist/esm/index.d.ts +11 -10
- package/dist/esm/index.js +481 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/index.d.ts +2 -3
- package/dist/esm/utils/index.js +3 -1
- package/package.json +7 -13
- package/dist/cjs/error-lBRMiMeF.d.cts +0 -17
- package/dist/cjs/options/index.cjs +0 -1
- package/dist/cjs/options/index.cjs.map +0 -1
- package/dist/cjs/options/index.d.cts +0 -25
- package/dist/esm/chunk-DQY5GNZB.js +0 -1
- package/dist/esm/chunk-DQY5GNZB.js.map +0 -1
- package/dist/esm/chunk-MOMG57MZ.js +0 -1
- package/dist/esm/error-lBRMiMeF.d.ts +0 -17
- package/dist/esm/options/index.d.ts +0 -25
- package/dist/esm/options/index.js +0 -1
- package/dist/esm/options/index.js.map +0 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1 +1,773 @@
|
|
|
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,{HTTPError:()=>a,callApi:()=>L,createFetchClient:()=>U,definePlugin:()=>x}),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=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)}},i=e=>e instanceof a||d(e)&&"HTTPError"===e.name&&!0===e.isHTTPError,l=e=>Array.isArray(e),u=e=>"object"==typeof e&&null!==e,c=e=>"[object Object]"===Object.prototype.toString.call(e),d=e=>{if(!c(e))return!1;const r=e?.constructor;if(void 0===r)return!0;const t=r.prototype;return!!c(t)&&(!!Object.hasOwn(t,"isPrototypeOf")&&Object.getPrototypeOf(e)===Object.prototype)},p=e=>"function"==typeof e,y=e=>"string"==typeof e,f=e=>p(e)?e():e,h=e=>{if(void 0!==e){if(y(e)||null===e)return{Authorization:`Bearer ${e}`};switch(e.type){case"Basic":{const r=f(e.username),t=f(e.password);if(void 0===r||void 0===t)return;return{Authorization:`Basic ${globalThis.btoa(`${r}:${t}`)}`}}case"Custom":{const r=f(e.value);if(void 0===r)return;return{Authorization:`${f(e.prefix)} ${r}`}}default:{const r=f(e.bearer),t=f(e.token);return"token"in e&&void 0!==t?{Authorization:`Token ${t}`}:void 0!==r&&{Authorization:`Bearer ${r}`}}}}},m=["extend","dedupeKey"],g=["body","integrity","method","headers","signal","cache","redirect","window","credentials","keepalive","referrer","priority","mode","referrerPolicy"],w={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"},b=["GET","POST"],E=Object.keys(w).map(Number),R=(e,r)=>{const t={},o=new Set(r);for(const[r,s]of Object.entries(e))o.has(r)||(t[r]=s);return t},S=(e,r)=>{const t={},o=new Set(r);for(const[r,s]of Object.entries(e))o.has(r)&&(t[r]=s);return t},O=e=>!e||d(e)?e:Object.fromEntries(e),v=e=>{const{auth:r,baseHeaders:t,body:o,headers:s}=e;if(!Boolean(t||s||o||r))return;const n={...h(r),...O(t),...O(s)};return y(a=o)&&a.includes("=")?(n["Content-Type"]="application/x-www-form-urlencoded",n):((d(o)||y(o)&&o.startsWith("{"))&&(n["Content-Type"]="application/json",n.Accept="application/json"),n);var a},q=(...e)=>Promise.all(e),T=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},D=async e=>{const{$RequestInfoCache:r,newFetchController:t,options:o,request:s}=e,n=o.dedupeKey??("cancel"===o.dedupeStrategy||"defer"===o.dedupeStrategy?`${o.fullURL}-${JSON.stringify({options:o,request:s})}`:null),a=null!==n?r:null;null!==n&&await T(.1);const i=a?.get(n);return{handleRequestCancelStrategy:()=>{if(!(i&&"cancel"===o.dedupeStrategy))return;const e=o.dedupeKey?`Duplicate request detected - Aborting previous request with key '${o.dedupeKey}' as a new request was initiated`:`Duplicate request detected - Aborting previous request to '${o.fullURL}' as a new request with identical options was initiated`,r=new DOMException(e,"AbortError");return i.controller.abort(r),Promise.resolve()},handleRequestDeferStrategy:()=>{const e=(e=>{if(e)return e;if("undefined"!=typeof globalThis&&p(globalThis.fetch))return globalThis.fetch;throw new Error("No fetch implementation found")})(o.customFetchImpl),r=i&&"defer"===o.dedupeStrategy?i.responsePromise:e(o.fullURL,s);return a?.set(n,{controller:t,responsePromise:r}),r},removeDedupeKeyFromCache:()=>a?.delete(n)}},x=e=>e,j=(e,r)=>async t=>{if("sequential"!==r){if("parallel"===r){const r=[...e];await Promise.all(r.map((e=>e?.(t))))}}else for(const r of e)await(r?.(t))},M={onError:new Set,onRequest:new Set,onRequestError:new Set,onResponse:new Set,onResponseError:new Set,onRetry:new Set,onSuccess:new Set},P=(e,r)=>e?p(e)?e(r):e:[],$=async(e,r,t)=>{const o=((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(o,r))throw new Error(`Invalid response type: ${r}`);return await o[r]()},k=(e,r)=>{const t=e["~retryCount"]??0;return{getDelay:()=>"exponential"===e.retryStrategy?((e,r)=>{const t=r.retryMaxDelay??1e4,o=(r.retryDelay??1e3)*2**e;return Math.min(o,t)})(t,e):(e=>e.retryDelay??1e3)(e),shouldAttemptRetry:async()=>{const o=await(e.retryCondition?.(r))??!0,s=(e.retryAttempts??0)>t&&o;if("HTTPError"!==r.error.name)return s;const n=!!r.request.method&&e.retryMethods?.includes(r.request.method);return!!r.response?.status&&e.retryStatusCodes?.includes(r.response.status)&&n&&s}}},A=(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}&${t}`:`${e}?${t}`},C=(e,r,t)=>{if(!e)return;const o=((e,r)=>{if(!r)return e;let t=e;if(l(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 A(o,t)},H=async(e,r,t)=>{const o=t?t(e):e,s=r?await(async(e,r)=>{const t=await e["~standard"].validate(r);if(t.issues)throw new Error(JSON.stringify(t.issues,null,2),{cause:t.issues});return t.value})(r,o):o;return s},U=e=>{const[r,t]=(e=>[S(e,g),R(e,[...g,...m])])(e??{}),o=new Map,s=async(...e)=>{const[n,c={}]=e,[f,h]=(e=>[S(e,g),R(e,g)])(c),m={};for(const e of Object.keys(M)){const r=(w=t[e],O=h[e],l(w)?[w,O].flat():O??w);m[e]=r}var w,O;const x={baseURL:"",bodySerializer:JSON.stringify,dedupeStrategy:"cancel",defaultErrorMessage:"Failed to fetch data from server!",mergedHooksExecutionMode:"parallel",mergedHooksExecutionOrder:"mainHooksAfterPlugins",responseType:"json",resultMode:"all",retryAttempts:0,retryDelay:1e3,retryMaxDelay:1e4,retryMethods:b,retryStatusCodes:E,retryStrategy:"linear",...t,...h,...m},A=f.body??r.body,U={...r,...f,body:d(A)?x.bodySerializer(A):A,headers:v({auth:x.auth,baseHeaders:r.headers,body:A,headers:f.headers}),signal:f.signal??r.signal},{resolvedHooks:L,resolvedOptions:W,resolvedRequestOptions:B,url:z}=await(async e=>{const{initURL:r,options:t,request:o}=e,s=structuredClone(M),n=()=>{for(const e of Object.keys(M)){const r=t[e];s[e].add(r)}},a=e=>{for(const r of Object.keys(M)){const t=e[r];s[r].add(t)}};"mainHooksBeforePlugins"===t.mergedHooksExecutionOrder&&n();const i=[...P(t.plugins,e),...P(t.extend?.plugins,e)];let l=r,u=t,c=o;const p=async e=>{if(!e)return;const s=await e({initURL:r,options:t,request:o});d(s)&&(y(s.initURL)&&(l=s.initURL),d(s.request)&&(c=s.request),d(s.options)&&(u=s.options))};for(const e of i)await p(e.init),e.hooks&&a(e.hooks);t.mergedHooksExecutionOrder&&"mainHooksAfterPlugins"!==t.mergedHooksExecutionOrder||n();const f={};for(const[e,r]of Object.entries(s)){const o=[...r].flat(),s=j(o,t.mergedHooksExecutionMode);f[e]=s}return{resolvedHooks:f,resolvedOptions:u,resolvedRequestOptions:c,url:l?.toString()}})({initURL:n,options:x,request:U}),F=`${W.baseURL}${C(z,W.params,W.query)}`,N={...W,...L,fullURL:F,initURL:n.toString()},K=new AbortController,I=null!=N.timeout?(G=N.timeout,AbortSignal.timeout(G)):null;var G;const J=((...e)=>AbortSignal.any(e.filter(Boolean)))(B.signal,I,K.signal),_={...B,signal:J},{handleRequestCancelStrategy:Q,handleRequestDeferStrategy:V,removeDedupeKeyFromCache:X}=await D({$RequestInfoCache:o,newFetchController:K,options:N,request:_});await Q();try{await q(N.onRequest({options:N,request:_})),_.headers=v({auth:N.auth,baseHeaders:r.headers,body:A,headers:_.headers});const e=await V(),t="defer"===N.dedupeStrategy||N.cloneResponse,{schemas:o,validators:s}=(e=>({schemas:e.schemas&&{...e.schemas,...e.extend?.schemas},validators:e.validators&&{...e.validators,...e.extend?.validators}}))(N);if(!e.ok){const r=await $(t?e.clone():e,N.responseType,N.responseParser),n=await H(r,o?.errorData,s?.errorData);throw new a({defaultErrorMessage:N.defaultErrorMessage,errorData:n,response:e})}const n=await $(t?e.clone():e,N.responseType,N.responseParser),i={data:await H(n,o?.data,s?.data),options:N,request:_,response:N.cloneResponse?e.clone():e};return await q(N.onSuccess(i),N.onResponse({...i,error:null})),await(e=>{const{data:r,response:t,resultMode:o}=e,s={data:r,error:null,response:t};return o?{all:s,allWithException:s,allWithoutResponse:R(s,["response"]),onlyError:s.error,onlyResponse:s.response,onlyResponseWithException:s.response,onlySuccess:s.data,onlySuccessWithException:s.data}[o]:s})({data:i.data,response:i.response,resultMode:N.resultMode})}catch(e){const{apiDetails:r,getErrorResult:t}=(e=>{const{cloneResponse:r,defaultErrorMessage:t,error:o,message:s,resultMode:n}=e;let a={data:null,error:{errorData:o,message:s??o.message,name:o.name},response:null};if(i(o)){const{errorData:e,message:s=t,name:n,response:i}=o;a={data:null,error:{errorData:e,message:s,name:n},response:r?i.clone():i}}const l={all:a,allWithException:a,allWithoutResponse:R(a,["response"]),onlyError:a.error,onlyResponse:a.response,onlyResponseWithException:a.response,onlySuccess:a.data,onlySuccessWithException:a.data};return{apiDetails:a,getErrorResult:e=>{const r=l[n??"all"];return u(e)?{...r,...e}:r}}})({cloneResponse:N.cloneResponse,defaultErrorMessage:N.defaultErrorMessage,error:e,resultMode:N.resultMode}),o={error:r.error,options:N,request:_,response:r.response},{getDelay:a,shouldAttemptRetry:l}=k(N,o);if(!J.aborted&&await l()){await q(N.onRetry(o));const e=a();await T(e);const r={...c,"~retryCount":(N["~retryCount"]??0)+1};return await s(n,r)}const d=p(N.throwOnError)?N.throwOnError(o):N.throwOnError,y=()=>{if(d)throw r.error};if(i(e))return await q(N.onResponseError(o),N.onError(o),N.onResponse({...o,data:null})),y(),t();if(e instanceof DOMException&&"AbortError"===e.name){const{message:r,name:o}=e;return console.error(`${o}:`,r),y(),t()}if(e instanceof DOMException&&"TimeoutError"===e.name){const r=`Request timed out after ${N.timeout}ms`;return console.error(`${e.name}:`,r),y(),t({message:r})}return await q(N.onRequestError(o),N.onError(o)),y(),t()}finally{X()}};return s.create=U,s},L=U();//# sourceMappingURL=index.cjs.map
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
HTTPError: () => HTTPError,
|
|
24
|
+
callApi: () => callApi,
|
|
25
|
+
createFetchClient: () => createFetchClient,
|
|
26
|
+
defineParameters: () => defineParameters,
|
|
27
|
+
definePlugin: () => definePlugin
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/error.ts
|
|
32
|
+
var resolveErrorResult = (info) => {
|
|
33
|
+
const { cloneResponse, defaultErrorMessage, error, message: customErrorMessage, resultMode } = info;
|
|
34
|
+
let apiDetails = {
|
|
35
|
+
data: null,
|
|
36
|
+
error: {
|
|
37
|
+
errorData: error,
|
|
38
|
+
message: customErrorMessage ?? error.message,
|
|
39
|
+
name: error.name
|
|
40
|
+
},
|
|
41
|
+
response: null
|
|
42
|
+
};
|
|
43
|
+
if (isHTTPErrorInstance(error)) {
|
|
44
|
+
const { errorData, message = defaultErrorMessage, name, response } = error;
|
|
45
|
+
apiDetails = {
|
|
46
|
+
data: null,
|
|
47
|
+
error: {
|
|
48
|
+
errorData,
|
|
49
|
+
message,
|
|
50
|
+
name
|
|
51
|
+
},
|
|
52
|
+
response: cloneResponse ? response.clone() : response
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const resultModeMap = {
|
|
56
|
+
all: apiDetails,
|
|
57
|
+
allWithException: apiDetails,
|
|
58
|
+
allWithoutResponse: omitKeys(apiDetails, ["response"]),
|
|
59
|
+
onlyError: apiDetails.error,
|
|
60
|
+
onlyResponse: apiDetails.response,
|
|
61
|
+
onlyResponseWithException: apiDetails.response,
|
|
62
|
+
onlySuccess: apiDetails.data,
|
|
63
|
+
onlySuccessWithException: apiDetails.data
|
|
64
|
+
};
|
|
65
|
+
const getErrorResult = (customInfo) => {
|
|
66
|
+
const errorResult = resultModeMap[resultMode ?? "all"];
|
|
67
|
+
return isObject(customInfo) ? { ...errorResult, ...customInfo } : errorResult;
|
|
68
|
+
};
|
|
69
|
+
return { apiDetails, getErrorResult };
|
|
70
|
+
};
|
|
71
|
+
var HTTPError = class extends Error {
|
|
72
|
+
errorData;
|
|
73
|
+
isHTTPError = true;
|
|
74
|
+
name = "HTTPError";
|
|
75
|
+
response;
|
|
76
|
+
constructor(errorDetails, errorOptions) {
|
|
77
|
+
const { defaultErrorMessage, errorData, response } = errorDetails;
|
|
78
|
+
super(errorData?.message ?? defaultErrorMessage, errorOptions);
|
|
79
|
+
this.errorData = errorData;
|
|
80
|
+
this.response = response;
|
|
81
|
+
Error.captureStackTrace(this, this.constructor);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/utils/type-guards.ts
|
|
86
|
+
var isHTTPErrorInstance = (error) => {
|
|
87
|
+
return (
|
|
88
|
+
// prettier-ignore
|
|
89
|
+
error instanceof HTTPError || isPlainObject(error) && error.name === "HTTPError" && error.isHTTPError === true
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
var isArray = (value) => Array.isArray(value);
|
|
93
|
+
var isObject = (value) => typeof value === "object" && value !== null;
|
|
94
|
+
var hasObjectPrototype = (value) => {
|
|
95
|
+
return Object.prototype.toString.call(value) === "[object Object]";
|
|
96
|
+
};
|
|
97
|
+
var isPlainObject = (value) => {
|
|
98
|
+
if (!hasObjectPrototype(value)) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
const constructor = value?.constructor;
|
|
102
|
+
if (constructor === void 0) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
const prototype = constructor.prototype;
|
|
106
|
+
if (!hasObjectPrototype(prototype)) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (!Object.hasOwn(prototype, "isPrototypeOf")) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
};
|
|
117
|
+
var isFunction = (value) => typeof value === "function";
|
|
118
|
+
var isQueryString = (value) => isString(value) && value.includes("=");
|
|
119
|
+
var isString = (value) => typeof value === "string";
|
|
120
|
+
|
|
121
|
+
// src/auth.ts
|
|
122
|
+
var getValue = (value) => {
|
|
123
|
+
return isFunction(value) ? value() : value;
|
|
124
|
+
};
|
|
125
|
+
var getAuthHeader = (auth) => {
|
|
126
|
+
if (auth === void 0) return;
|
|
127
|
+
if (isString(auth) || auth === null) {
|
|
128
|
+
return { Authorization: `Bearer ${auth}` };
|
|
129
|
+
}
|
|
130
|
+
switch (auth.type) {
|
|
131
|
+
case "Basic": {
|
|
132
|
+
const username = getValue(auth.username);
|
|
133
|
+
const password = getValue(auth.password);
|
|
134
|
+
if (username === void 0 || password === void 0) return;
|
|
135
|
+
return {
|
|
136
|
+
Authorization: `Basic ${globalThis.btoa(`${username}:${password}`)}`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
case "Custom": {
|
|
140
|
+
const value = getValue(auth.value);
|
|
141
|
+
if (value === void 0) return;
|
|
142
|
+
const prefix = getValue(auth.prefix);
|
|
143
|
+
return {
|
|
144
|
+
Authorization: `${prefix} ${value}`
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
default: {
|
|
148
|
+
const bearer = getValue(auth.bearer);
|
|
149
|
+
const token = getValue(auth.token);
|
|
150
|
+
if ("token" in auth && token !== void 0) {
|
|
151
|
+
return { Authorization: `Token ${token}` };
|
|
152
|
+
}
|
|
153
|
+
return bearer !== void 0 && { Authorization: `Bearer ${bearer}` };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/utils/type-helpers.ts
|
|
159
|
+
var defineEnum = (value) => value;
|
|
160
|
+
|
|
161
|
+
// src/types/common.ts
|
|
162
|
+
var optionsEnumToExtendFromBase = defineEnum(["plugins", "validators", "schemas"]);
|
|
163
|
+
var optionsEnumToOmitFromBase = defineEnum(["extend", "dedupeKey"]);
|
|
164
|
+
|
|
165
|
+
// src/utils/constants.ts
|
|
166
|
+
var fetchSpecificKeys = defineEnum([
|
|
167
|
+
"body",
|
|
168
|
+
"integrity",
|
|
169
|
+
"method",
|
|
170
|
+
"headers",
|
|
171
|
+
"signal",
|
|
172
|
+
"cache",
|
|
173
|
+
"redirect",
|
|
174
|
+
"window",
|
|
175
|
+
"credentials",
|
|
176
|
+
"keepalive",
|
|
177
|
+
"referrer",
|
|
178
|
+
"priority",
|
|
179
|
+
"mode",
|
|
180
|
+
"referrerPolicy"
|
|
181
|
+
]);
|
|
182
|
+
var retryStatusCodesLookup = defineEnum({
|
|
183
|
+
408: "Request Timeout",
|
|
184
|
+
409: "Conflict",
|
|
185
|
+
425: "Too Early",
|
|
186
|
+
429: "Too Many Requests",
|
|
187
|
+
500: "Internal Server Error",
|
|
188
|
+
502: "Bad Gateway",
|
|
189
|
+
503: "Service Unavailable",
|
|
190
|
+
504: "Gateway Timeout"
|
|
191
|
+
});
|
|
192
|
+
var defaultRetryMethods = ["GET", "POST"];
|
|
193
|
+
var defaultRetryStatusCodes = Object.keys(retryStatusCodesLookup).map(Number);
|
|
194
|
+
|
|
195
|
+
// src/utils/common.ts
|
|
196
|
+
var omitKeys = (initialObject, keysToOmit) => {
|
|
197
|
+
const updatedObject = {};
|
|
198
|
+
const keysToOmitSet = new Set(keysToOmit);
|
|
199
|
+
for (const [key, value] of Object.entries(initialObject)) {
|
|
200
|
+
if (!keysToOmitSet.has(key)) {
|
|
201
|
+
updatedObject[key] = value;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return updatedObject;
|
|
205
|
+
};
|
|
206
|
+
var pickKeys = (initialObject, keysToPick) => {
|
|
207
|
+
const updatedObject = {};
|
|
208
|
+
const keysToPickSet = new Set(keysToPick);
|
|
209
|
+
for (const [key, value] of Object.entries(initialObject)) {
|
|
210
|
+
if (keysToPickSet.has(key)) {
|
|
211
|
+
updatedObject[key] = value;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return updatedObject;
|
|
215
|
+
};
|
|
216
|
+
var splitBaseConfig = (baseConfig) => [
|
|
217
|
+
pickKeys(baseConfig, fetchSpecificKeys),
|
|
218
|
+
omitKeys(baseConfig, [
|
|
219
|
+
...fetchSpecificKeys,
|
|
220
|
+
...optionsEnumToOmitFromBase
|
|
221
|
+
])
|
|
222
|
+
];
|
|
223
|
+
var splitConfig = (config) => [
|
|
224
|
+
pickKeys(config, fetchSpecificKeys),
|
|
225
|
+
omitKeys(config, fetchSpecificKeys)
|
|
226
|
+
];
|
|
227
|
+
var objectifyHeaders = (headers) => {
|
|
228
|
+
if (!headers || isPlainObject(headers)) {
|
|
229
|
+
return headers;
|
|
230
|
+
}
|
|
231
|
+
return Object.fromEntries(headers);
|
|
232
|
+
};
|
|
233
|
+
var toQueryString = (params) => {
|
|
234
|
+
if (!params) {
|
|
235
|
+
console.error("toQueryString:", "No query params provided!");
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return new URLSearchParams(params).toString();
|
|
239
|
+
};
|
|
240
|
+
var mergeAndResolveHeaders = (options) => {
|
|
241
|
+
const { auth, baseHeaders, body, headers } = options;
|
|
242
|
+
const shouldResolveHeaders = Boolean(baseHeaders || headers || body || auth);
|
|
243
|
+
if (!shouldResolveHeaders) return;
|
|
244
|
+
const headersObject = {
|
|
245
|
+
...getAuthHeader(auth),
|
|
246
|
+
...objectifyHeaders(baseHeaders),
|
|
247
|
+
...objectifyHeaders(headers)
|
|
248
|
+
};
|
|
249
|
+
if (isQueryString(body)) {
|
|
250
|
+
headersObject["Content-Type"] = "application/x-www-form-urlencoded";
|
|
251
|
+
return headersObject;
|
|
252
|
+
}
|
|
253
|
+
if (isPlainObject(body) || isString(body) && body.startsWith("{")) {
|
|
254
|
+
headersObject["Content-Type"] = "application/json";
|
|
255
|
+
headersObject.Accept = "application/json";
|
|
256
|
+
}
|
|
257
|
+
return headersObject;
|
|
258
|
+
};
|
|
259
|
+
var combineHooks = (baseInterceptor, interceptor) => {
|
|
260
|
+
if (isArray(baseInterceptor)) {
|
|
261
|
+
return [baseInterceptor, interceptor].flat();
|
|
262
|
+
}
|
|
263
|
+
return interceptor ?? baseInterceptor;
|
|
264
|
+
};
|
|
265
|
+
var getFetchImpl = (customFetchImpl) => {
|
|
266
|
+
if (customFetchImpl) {
|
|
267
|
+
return customFetchImpl;
|
|
268
|
+
}
|
|
269
|
+
if (typeof globalThis !== "undefined" && isFunction(globalThis.fetch)) {
|
|
270
|
+
return globalThis.fetch;
|
|
271
|
+
}
|
|
272
|
+
throw new Error("No fetch implementation found");
|
|
273
|
+
};
|
|
274
|
+
var executeHooks = (...interceptors) => Promise.all(interceptors);
|
|
275
|
+
var PromiseWithResolvers = () => {
|
|
276
|
+
let reject;
|
|
277
|
+
let resolve;
|
|
278
|
+
const promise = new Promise((res, rej) => {
|
|
279
|
+
resolve = res;
|
|
280
|
+
reject = rej;
|
|
281
|
+
});
|
|
282
|
+
return { promise, reject, resolve };
|
|
283
|
+
};
|
|
284
|
+
var waitUntil = (delay) => {
|
|
285
|
+
if (delay === 0) return;
|
|
286
|
+
const { promise, resolve } = PromiseWithResolvers();
|
|
287
|
+
setTimeout(resolve, delay);
|
|
288
|
+
return promise;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/dedupe.ts
|
|
292
|
+
var createDedupeStrategy = async (context) => {
|
|
293
|
+
const { $RequestInfoCache, newFetchController, options, request } = context;
|
|
294
|
+
const generateDedupeKey = () => {
|
|
295
|
+
const shouldHaveDedupeKey = options.dedupeStrategy === "cancel" || options.dedupeStrategy === "defer";
|
|
296
|
+
if (!shouldHaveDedupeKey) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
return `${options.fullURL}-${JSON.stringify({ options, request })}`;
|
|
300
|
+
};
|
|
301
|
+
const dedupeKey = options.dedupeKey ?? generateDedupeKey();
|
|
302
|
+
const $RequestInfoCacheOrNull = dedupeKey !== null ? $RequestInfoCache : null;
|
|
303
|
+
if (dedupeKey !== null) {
|
|
304
|
+
await waitUntil(0.1);
|
|
305
|
+
}
|
|
306
|
+
const prevRequestInfo = $RequestInfoCacheOrNull?.get(dedupeKey);
|
|
307
|
+
const handleRequestCancelStrategy = () => {
|
|
308
|
+
const shouldCancelRequest = prevRequestInfo && options.dedupeStrategy === "cancel";
|
|
309
|
+
if (!shouldCancelRequest) return;
|
|
310
|
+
const message = options.dedupeKey ? `Duplicate request detected - Aborting previous request with key '${options.dedupeKey}' as a new request was initiated` : `Duplicate request detected - Aborting previous request to '${options.fullURL}' as a new request with identical options was initiated`;
|
|
311
|
+
const reason = new DOMException(message, "AbortError");
|
|
312
|
+
prevRequestInfo.controller.abort(reason);
|
|
313
|
+
return Promise.resolve();
|
|
314
|
+
};
|
|
315
|
+
const handleRequestDeferStrategy = () => {
|
|
316
|
+
const fetchApi = getFetchImpl(options.customFetchImpl);
|
|
317
|
+
const shouldUsePromiseFromCache = prevRequestInfo && options.dedupeStrategy === "defer";
|
|
318
|
+
const responsePromise = shouldUsePromiseFromCache ? prevRequestInfo.responsePromise : fetchApi(options.fullURL, request);
|
|
319
|
+
$RequestInfoCacheOrNull?.set(dedupeKey, { controller: newFetchController, responsePromise });
|
|
320
|
+
return responsePromise;
|
|
321
|
+
};
|
|
322
|
+
const removeDedupeKeyFromCache = () => $RequestInfoCacheOrNull?.delete(dedupeKey);
|
|
323
|
+
return {
|
|
324
|
+
handleRequestCancelStrategy,
|
|
325
|
+
handleRequestDeferStrategy,
|
|
326
|
+
removeDedupeKeyFromCache
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// src/plugins.ts
|
|
331
|
+
var definePlugin = (plugin) => {
|
|
332
|
+
return plugin;
|
|
333
|
+
};
|
|
334
|
+
var createMergedHook = (hooks, mergedHooksExecutionMode) => {
|
|
335
|
+
return async (ctx) => {
|
|
336
|
+
if (mergedHooksExecutionMode === "sequential") {
|
|
337
|
+
for (const hook of hooks) {
|
|
338
|
+
await hook?.(ctx);
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (mergedHooksExecutionMode === "parallel") {
|
|
343
|
+
const hookArray = [...hooks];
|
|
344
|
+
await Promise.all(hookArray.map((uniqueHook) => uniqueHook?.(ctx)));
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
var hooksEnum = {
|
|
349
|
+
onError: /* @__PURE__ */ new Set(),
|
|
350
|
+
onRequest: /* @__PURE__ */ new Set(),
|
|
351
|
+
onRequestError: /* @__PURE__ */ new Set(),
|
|
352
|
+
onResponse: /* @__PURE__ */ new Set(),
|
|
353
|
+
onResponseError: /* @__PURE__ */ new Set(),
|
|
354
|
+
onRetry: /* @__PURE__ */ new Set(),
|
|
355
|
+
onSuccess: /* @__PURE__ */ new Set()
|
|
356
|
+
};
|
|
357
|
+
var getPluginArray = (plugins, context) => {
|
|
358
|
+
if (!plugins) {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
return isFunction(plugins) ? plugins(context) : plugins;
|
|
362
|
+
};
|
|
363
|
+
var initializePlugins = async (context) => {
|
|
364
|
+
const { initURL, options, request } = context;
|
|
365
|
+
const hookRegistries = structuredClone(hooksEnum);
|
|
366
|
+
const addMainHooks = () => {
|
|
367
|
+
for (const key of Object.keys(hooksEnum)) {
|
|
368
|
+
const mainHook = options[key];
|
|
369
|
+
hookRegistries[key].add(mainHook);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
const addPluginHooks = (pluginHooks) => {
|
|
373
|
+
for (const key of Object.keys(hooksEnum)) {
|
|
374
|
+
const pluginHook = pluginHooks[key];
|
|
375
|
+
hookRegistries[key].add(pluginHook);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
if (options.mergedHooksExecutionOrder === "mainHooksBeforePlugins") {
|
|
379
|
+
addMainHooks();
|
|
380
|
+
}
|
|
381
|
+
const resolvedPlugins = [
|
|
382
|
+
...getPluginArray(options.plugins, context),
|
|
383
|
+
...getPluginArray(options.extend?.plugins, context)
|
|
384
|
+
];
|
|
385
|
+
let resolvedUrl = initURL;
|
|
386
|
+
let resolvedOptions = options;
|
|
387
|
+
let resolvedRequestOptions = request;
|
|
388
|
+
const executePluginInit = async (pluginInit) => {
|
|
389
|
+
if (!pluginInit) return;
|
|
390
|
+
const initResult = await pluginInit({ initURL, options, request });
|
|
391
|
+
if (!isPlainObject(initResult)) return;
|
|
392
|
+
if (isString(initResult.initURL)) {
|
|
393
|
+
resolvedUrl = initResult.initURL;
|
|
394
|
+
}
|
|
395
|
+
if (isPlainObject(initResult.request)) {
|
|
396
|
+
resolvedRequestOptions = initResult.request;
|
|
397
|
+
}
|
|
398
|
+
if (isPlainObject(initResult.options)) {
|
|
399
|
+
resolvedOptions = initResult.options;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
for (const plugin of resolvedPlugins) {
|
|
403
|
+
await executePluginInit(plugin.init);
|
|
404
|
+
if (!plugin.hooks) continue;
|
|
405
|
+
addPluginHooks(plugin.hooks);
|
|
406
|
+
}
|
|
407
|
+
if (!options.mergedHooksExecutionOrder || options.mergedHooksExecutionOrder === "mainHooksAfterPlugins") {
|
|
408
|
+
addMainHooks();
|
|
409
|
+
}
|
|
410
|
+
const resolvedHooks = {};
|
|
411
|
+
for (const [key, hookRegistry] of Object.entries(hookRegistries)) {
|
|
412
|
+
const flattenedHookArray = [...hookRegistry].flat();
|
|
413
|
+
const mergedHook = createMergedHook(flattenedHookArray, options.mergedHooksExecutionMode);
|
|
414
|
+
resolvedHooks[key] = mergedHook;
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
resolvedHooks,
|
|
418
|
+
resolvedOptions,
|
|
419
|
+
resolvedRequestOptions,
|
|
420
|
+
url: resolvedUrl?.toString()
|
|
421
|
+
};
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// src/response.ts
|
|
425
|
+
var getResponseType = (response, parser) => ({
|
|
426
|
+
arrayBuffer: () => response.arrayBuffer(),
|
|
427
|
+
blob: () => response.blob(),
|
|
428
|
+
formData: () => response.formData(),
|
|
429
|
+
json: async () => {
|
|
430
|
+
if (parser) {
|
|
431
|
+
const text = await response.text();
|
|
432
|
+
return parser(text);
|
|
433
|
+
}
|
|
434
|
+
return response.json();
|
|
435
|
+
},
|
|
436
|
+
stream: () => response.body,
|
|
437
|
+
text: () => response.text()
|
|
438
|
+
});
|
|
439
|
+
var resolveResponseData = async (response, responseType, parser) => {
|
|
440
|
+
const RESPONSE_TYPE_LOOKUP = getResponseType(response, parser);
|
|
441
|
+
if (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, responseType)) {
|
|
442
|
+
throw new Error(`Invalid response type: ${responseType}`);
|
|
443
|
+
}
|
|
444
|
+
const responseData = await RESPONSE_TYPE_LOOKUP[responseType]();
|
|
445
|
+
return responseData;
|
|
446
|
+
};
|
|
447
|
+
var resolveSuccessResult = (info) => {
|
|
448
|
+
const { data, response, resultMode } = info;
|
|
449
|
+
const apiDetails = { data, error: null, response };
|
|
450
|
+
if (!resultMode) {
|
|
451
|
+
return apiDetails;
|
|
452
|
+
}
|
|
453
|
+
const resultModeMap = {
|
|
454
|
+
all: apiDetails,
|
|
455
|
+
allWithException: apiDetails,
|
|
456
|
+
allWithoutResponse: omitKeys(apiDetails, ["response"]),
|
|
457
|
+
onlyError: apiDetails.error,
|
|
458
|
+
onlyResponse: apiDetails.response,
|
|
459
|
+
onlyResponseWithException: apiDetails.response,
|
|
460
|
+
onlySuccess: apiDetails.data,
|
|
461
|
+
onlySuccessWithException: apiDetails.data
|
|
462
|
+
};
|
|
463
|
+
return resultModeMap[resultMode];
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// src/retry.ts
|
|
467
|
+
var getLinearDelay = (options) => options.retryDelay ?? 1e3;
|
|
468
|
+
var getExponentialDelay = (currentAttemptCount, options) => {
|
|
469
|
+
const maxDelay = options.retryMaxDelay ?? 1e4;
|
|
470
|
+
const exponentialDelay = (options.retryDelay ?? 1e3) * 2 ** currentAttemptCount;
|
|
471
|
+
return Math.min(exponentialDelay, maxDelay);
|
|
472
|
+
};
|
|
473
|
+
var createRetryStrategy = (options, ctx) => {
|
|
474
|
+
const currentRetryCount = options["~retryCount"] ?? 0;
|
|
475
|
+
const getDelay = () => {
|
|
476
|
+
if (options.retryStrategy === "exponential") {
|
|
477
|
+
return getExponentialDelay(currentRetryCount, options);
|
|
478
|
+
}
|
|
479
|
+
return getLinearDelay(options);
|
|
480
|
+
};
|
|
481
|
+
const shouldAttemptRetry = async () => {
|
|
482
|
+
const customRetryCondition = await options.retryCondition?.(ctx) ?? true;
|
|
483
|
+
const maxRetryAttempts = options.retryAttempts ?? 0;
|
|
484
|
+
const baseRetryCondition = maxRetryAttempts > currentRetryCount && customRetryCondition;
|
|
485
|
+
if (ctx.error.name !== "HTTPError") {
|
|
486
|
+
return baseRetryCondition;
|
|
487
|
+
}
|
|
488
|
+
const includesMethod = (
|
|
489
|
+
// eslint-disable-next-line no-implicit-coercion -- Boolean doesn't narrow
|
|
490
|
+
!!ctx.request.method && options.retryMethods?.includes(ctx.request.method)
|
|
491
|
+
);
|
|
492
|
+
const includesCodes = (
|
|
493
|
+
// eslint-disable-next-line no-implicit-coercion -- Boolean doesn't narrow
|
|
494
|
+
!!ctx.response?.status && options.retryStatusCodes?.includes(ctx.response.status)
|
|
495
|
+
);
|
|
496
|
+
return includesCodes && includesMethod && baseRetryCondition;
|
|
497
|
+
};
|
|
498
|
+
return {
|
|
499
|
+
getDelay,
|
|
500
|
+
shouldAttemptRetry
|
|
501
|
+
};
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// src/url.ts
|
|
505
|
+
var slash = "/";
|
|
506
|
+
var column = ":";
|
|
507
|
+
var mergeUrlWithParams = (url, params) => {
|
|
508
|
+
if (!params) {
|
|
509
|
+
return url;
|
|
510
|
+
}
|
|
511
|
+
let newUrl = url;
|
|
512
|
+
if (isArray(params)) {
|
|
513
|
+
const matchedParamArray = newUrl.split(slash).filter((param) => param.startsWith(column));
|
|
514
|
+
for (const [index, matchedParam] of matchedParamArray.entries()) {
|
|
515
|
+
const realParam = params[index];
|
|
516
|
+
newUrl = newUrl.replace(matchedParam, realParam);
|
|
517
|
+
}
|
|
518
|
+
return newUrl;
|
|
519
|
+
}
|
|
520
|
+
for (const [key, value] of Object.entries(params)) {
|
|
521
|
+
newUrl = newUrl.replace(`${column}${key}`, String(value));
|
|
522
|
+
}
|
|
523
|
+
return newUrl;
|
|
524
|
+
};
|
|
525
|
+
var questionMark = "?";
|
|
526
|
+
var ampersand = "&";
|
|
527
|
+
var mergeUrlWithQuery = (url, query) => {
|
|
528
|
+
if (!query) {
|
|
529
|
+
return url;
|
|
530
|
+
}
|
|
531
|
+
const queryString = toQueryString(query);
|
|
532
|
+
if (queryString?.length === 0) {
|
|
533
|
+
return url;
|
|
534
|
+
}
|
|
535
|
+
if (url.endsWith(questionMark)) {
|
|
536
|
+
return `${url}${queryString}`;
|
|
537
|
+
}
|
|
538
|
+
if (url.includes(questionMark)) {
|
|
539
|
+
return `${url}${ampersand}${queryString}`;
|
|
540
|
+
}
|
|
541
|
+
return `${url}${questionMark}${queryString}`;
|
|
542
|
+
};
|
|
543
|
+
var mergeUrlWithParamsAndQuery = (url, params, query) => {
|
|
544
|
+
if (!url) return;
|
|
545
|
+
const urlWithMergedParams = mergeUrlWithParams(url, params);
|
|
546
|
+
return mergeUrlWithQuery(urlWithMergedParams, query);
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
// src/utils/polyfills.ts
|
|
550
|
+
var createCombinedSignal = (...signals) => AbortSignal.any(signals.filter(Boolean));
|
|
551
|
+
var createTimeoutSignal = (milliseconds) => AbortSignal.timeout(milliseconds);
|
|
552
|
+
|
|
553
|
+
// src/validation.ts
|
|
554
|
+
var standardSchemaParser = async (schema, inputData) => {
|
|
555
|
+
const result = await schema["~standard"].validate(inputData);
|
|
556
|
+
if (result.issues) {
|
|
557
|
+
throw new Error(JSON.stringify(result.issues, null, 2), { cause: result.issues });
|
|
558
|
+
}
|
|
559
|
+
return result.value;
|
|
560
|
+
};
|
|
561
|
+
var createExtensibleSchemasAndValidators = (options) => {
|
|
562
|
+
const schemas = options.schemas && { ...options.schemas, ...options.extend?.schemas };
|
|
563
|
+
const validators = options.validators && { ...options.validators, ...options.extend?.validators };
|
|
564
|
+
return { schemas, validators };
|
|
565
|
+
};
|
|
566
|
+
var handleValidation = async (responseData, schema, validator) => {
|
|
567
|
+
const validResponseData = validator ? validator(responseData) : responseData;
|
|
568
|
+
const schemaValidResponseData = schema ? await standardSchemaParser(schema, validResponseData) : validResponseData;
|
|
569
|
+
return schemaValidResponseData;
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// src/createFetchClient.ts
|
|
573
|
+
var createFetchClient = (baseConfig) => {
|
|
574
|
+
const [baseFetchOptions, baseExtraOptions] = splitBaseConfig(baseConfig ?? {});
|
|
575
|
+
const $RequestInfoCache = /* @__PURE__ */ new Map();
|
|
576
|
+
const callApi2 = async (...parameters) => {
|
|
577
|
+
const [initURL, config = {}] = parameters;
|
|
578
|
+
const [fetchOptions, extraOptions] = splitConfig(config);
|
|
579
|
+
const initCombinedHooks = {};
|
|
580
|
+
for (const key of Object.keys(hooksEnum)) {
|
|
581
|
+
const combinedHook = combineHooks(
|
|
582
|
+
baseExtraOptions[key],
|
|
583
|
+
extraOptions[key]
|
|
584
|
+
);
|
|
585
|
+
initCombinedHooks[key] = combinedHook;
|
|
586
|
+
}
|
|
587
|
+
const defaultExtraOptions = {
|
|
588
|
+
baseURL: "",
|
|
589
|
+
bodySerializer: JSON.stringify,
|
|
590
|
+
dedupeStrategy: "cancel",
|
|
591
|
+
defaultErrorMessage: "Failed to fetch data from server!",
|
|
592
|
+
mergedHooksExecutionMode: "parallel",
|
|
593
|
+
mergedHooksExecutionOrder: "mainHooksAfterPlugins",
|
|
594
|
+
responseType: "json",
|
|
595
|
+
resultMode: "all",
|
|
596
|
+
retryAttempts: 0,
|
|
597
|
+
retryDelay: 1e3,
|
|
598
|
+
retryMaxDelay: 1e4,
|
|
599
|
+
retryMethods: defaultRetryMethods,
|
|
600
|
+
retryStatusCodes: defaultRetryStatusCodes,
|
|
601
|
+
retryStrategy: "linear",
|
|
602
|
+
...baseExtraOptions,
|
|
603
|
+
...extraOptions,
|
|
604
|
+
...initCombinedHooks
|
|
605
|
+
};
|
|
606
|
+
const body = fetchOptions.body ?? baseFetchOptions.body;
|
|
607
|
+
const defaultRequestOptions = {
|
|
608
|
+
...baseFetchOptions,
|
|
609
|
+
...fetchOptions,
|
|
610
|
+
body: isPlainObject(body) ? defaultExtraOptions.bodySerializer(body) : body,
|
|
611
|
+
headers: mergeAndResolveHeaders({
|
|
612
|
+
auth: defaultExtraOptions.auth,
|
|
613
|
+
baseHeaders: baseFetchOptions.headers,
|
|
614
|
+
body,
|
|
615
|
+
headers: fetchOptions.headers
|
|
616
|
+
}),
|
|
617
|
+
signal: fetchOptions.signal ?? baseFetchOptions.signal
|
|
618
|
+
};
|
|
619
|
+
const { resolvedHooks, resolvedOptions, resolvedRequestOptions, url } = await initializePlugins({
|
|
620
|
+
initURL,
|
|
621
|
+
options: defaultExtraOptions,
|
|
622
|
+
request: defaultRequestOptions
|
|
623
|
+
});
|
|
624
|
+
const fullURL = `${resolvedOptions.baseURL}${mergeUrlWithParamsAndQuery(url, resolvedOptions.params, resolvedOptions.query)}`;
|
|
625
|
+
const options = {
|
|
626
|
+
...resolvedOptions,
|
|
627
|
+
...resolvedHooks,
|
|
628
|
+
fullURL,
|
|
629
|
+
initURL: initURL.toString()
|
|
630
|
+
};
|
|
631
|
+
const newFetchController = new AbortController();
|
|
632
|
+
const timeoutSignal = options.timeout != null ? createTimeoutSignal(options.timeout) : null;
|
|
633
|
+
const combinedSignal = createCombinedSignal(
|
|
634
|
+
resolvedRequestOptions.signal,
|
|
635
|
+
timeoutSignal,
|
|
636
|
+
newFetchController.signal
|
|
637
|
+
);
|
|
638
|
+
const request = {
|
|
639
|
+
...resolvedRequestOptions,
|
|
640
|
+
signal: combinedSignal
|
|
641
|
+
};
|
|
642
|
+
const { handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache } = await createDedupeStrategy({ $RequestInfoCache, newFetchController, options, request });
|
|
643
|
+
await handleRequestCancelStrategy();
|
|
644
|
+
try {
|
|
645
|
+
await executeHooks(options.onRequest({ options, request }));
|
|
646
|
+
request.headers = mergeAndResolveHeaders({
|
|
647
|
+
auth: options.auth,
|
|
648
|
+
baseHeaders: baseFetchOptions.headers,
|
|
649
|
+
body,
|
|
650
|
+
headers: request.headers
|
|
651
|
+
});
|
|
652
|
+
const response = await handleRequestDeferStrategy();
|
|
653
|
+
const shouldCloneResponse = options.dedupeStrategy === "defer" || options.cloneResponse;
|
|
654
|
+
const { schemas, validators } = createExtensibleSchemasAndValidators(options);
|
|
655
|
+
if (!response.ok) {
|
|
656
|
+
const errorData = await resolveResponseData(
|
|
657
|
+
shouldCloneResponse ? response.clone() : response,
|
|
658
|
+
options.responseType,
|
|
659
|
+
options.responseParser
|
|
660
|
+
);
|
|
661
|
+
const validErrorData = await handleValidation(
|
|
662
|
+
errorData,
|
|
663
|
+
schemas?.errorData,
|
|
664
|
+
validators?.errorData
|
|
665
|
+
);
|
|
666
|
+
throw new HTTPError({
|
|
667
|
+
defaultErrorMessage: options.defaultErrorMessage,
|
|
668
|
+
errorData: validErrorData,
|
|
669
|
+
response
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
const successData = await resolveResponseData(
|
|
673
|
+
shouldCloneResponse ? response.clone() : response,
|
|
674
|
+
options.responseType,
|
|
675
|
+
options.responseParser
|
|
676
|
+
);
|
|
677
|
+
const validSuccessData = await handleValidation(successData, schemas?.data, validators?.data);
|
|
678
|
+
const successContext = {
|
|
679
|
+
data: validSuccessData,
|
|
680
|
+
options,
|
|
681
|
+
request,
|
|
682
|
+
response: options.cloneResponse ? response.clone() : response
|
|
683
|
+
};
|
|
684
|
+
await executeHooks(
|
|
685
|
+
options.onSuccess(successContext),
|
|
686
|
+
options.onResponse({ ...successContext, error: null })
|
|
687
|
+
);
|
|
688
|
+
return await resolveSuccessResult({
|
|
689
|
+
data: successContext.data,
|
|
690
|
+
response: successContext.response,
|
|
691
|
+
resultMode: options.resultMode
|
|
692
|
+
});
|
|
693
|
+
} catch (error) {
|
|
694
|
+
const { apiDetails, getErrorResult } = resolveErrorResult({
|
|
695
|
+
cloneResponse: options.cloneResponse,
|
|
696
|
+
defaultErrorMessage: options.defaultErrorMessage,
|
|
697
|
+
error,
|
|
698
|
+
resultMode: options.resultMode
|
|
699
|
+
});
|
|
700
|
+
const errorContext = {
|
|
701
|
+
error: apiDetails.error,
|
|
702
|
+
options,
|
|
703
|
+
request,
|
|
704
|
+
response: apiDetails.response
|
|
705
|
+
};
|
|
706
|
+
const { getDelay, shouldAttemptRetry } = createRetryStrategy(options, errorContext);
|
|
707
|
+
const shouldRetry = !combinedSignal.aborted && await shouldAttemptRetry();
|
|
708
|
+
if (shouldRetry) {
|
|
709
|
+
await executeHooks(options.onRetry(errorContext));
|
|
710
|
+
const delay = getDelay();
|
|
711
|
+
await waitUntil(delay);
|
|
712
|
+
const updatedOptions = {
|
|
713
|
+
...config,
|
|
714
|
+
"~retryCount": (options["~retryCount"] ?? 0) + 1
|
|
715
|
+
};
|
|
716
|
+
return await callApi2(initURL, updatedOptions);
|
|
717
|
+
}
|
|
718
|
+
const shouldThrowOnError = isFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError;
|
|
719
|
+
const handleThrowOnError = () => {
|
|
720
|
+
if (!shouldThrowOnError) return;
|
|
721
|
+
throw apiDetails.error;
|
|
722
|
+
};
|
|
723
|
+
if (isHTTPErrorInstance(error)) {
|
|
724
|
+
await executeHooks(
|
|
725
|
+
options.onResponseError(errorContext),
|
|
726
|
+
options.onError(errorContext),
|
|
727
|
+
options.onResponse({ ...errorContext, data: null })
|
|
728
|
+
);
|
|
729
|
+
handleThrowOnError();
|
|
730
|
+
return getErrorResult();
|
|
731
|
+
}
|
|
732
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
733
|
+
const { message, name } = error;
|
|
734
|
+
console.error(`${name}:`, message);
|
|
735
|
+
handleThrowOnError();
|
|
736
|
+
return getErrorResult();
|
|
737
|
+
}
|
|
738
|
+
if (error instanceof DOMException && error.name === "TimeoutError") {
|
|
739
|
+
const message = `Request timed out after ${options.timeout}ms`;
|
|
740
|
+
console.error(`${error.name}:`, message);
|
|
741
|
+
handleThrowOnError();
|
|
742
|
+
return getErrorResult({ message });
|
|
743
|
+
}
|
|
744
|
+
await executeHooks(
|
|
745
|
+
// == At this point only the request errors exist, so the request error interceptor is called
|
|
746
|
+
options.onRequestError(errorContext),
|
|
747
|
+
// == Also call the onError interceptor
|
|
748
|
+
options.onError(errorContext)
|
|
749
|
+
);
|
|
750
|
+
handleThrowOnError();
|
|
751
|
+
return getErrorResult();
|
|
752
|
+
} finally {
|
|
753
|
+
removeDedupeKeyFromCache();
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
callApi2.create = createFetchClient;
|
|
757
|
+
return callApi2;
|
|
758
|
+
};
|
|
759
|
+
var callApi = createFetchClient();
|
|
760
|
+
|
|
761
|
+
// src/defineParameters.ts
|
|
762
|
+
var defineParameters = (...parameters) => {
|
|
763
|
+
return parameters;
|
|
764
|
+
};
|
|
765
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
766
|
+
0 && (module.exports = {
|
|
767
|
+
HTTPError,
|
|
768
|
+
callApi,
|
|
769
|
+
createFetchClient,
|
|
770
|
+
defineParameters,
|
|
771
|
+
definePlugin
|
|
772
|
+
});
|
|
773
|
+
//# sourceMappingURL=index.cjs.map
|