soon-fetch 2.0.1 → 2.1.1
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 +143 -16
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +46 -44
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
- [Restful Url Params](#restful-url-params)
|
|
21
21
|
- [Timeout](#timeout)
|
|
22
22
|
- [Rapid Define APIs](#rapid-define-apis)
|
|
23
|
+
- [API](#api)
|
|
23
24
|
- [Support Me](#support-me)
|
|
24
25
|
|
|
25
26
|
### Example
|
|
@@ -31,19 +32,12 @@
|
|
|
31
32
|
import { createSoon, parseUrlOptions, type SoonOptions } from "soon-fetch";
|
|
32
33
|
|
|
33
34
|
const request = <T>(url: string, options?: SoonOptions) => {
|
|
34
|
-
// _url : url handled with baseURL , options.query , options.params
|
|
35
|
-
// _options: 1. merge baseOptions and options,
|
|
36
|
-
// 2. transfer merged options from SoonOptions to raw fetch options
|
|
37
|
-
// 3. json object body would be auto stringified and add header { "Content-Type": "application/json" }
|
|
38
35
|
const [_url, _options] = parseUrlOptions({
|
|
39
36
|
url,
|
|
40
37
|
options,
|
|
41
38
|
baseURL: "/api",
|
|
42
39
|
baseOptions: {
|
|
43
|
-
// would override by options.timeout
|
|
44
40
|
timeout: 20 * 1000,
|
|
45
|
-
// would merged with options.headers
|
|
46
|
-
// the same-key header would override by options.headers
|
|
47
41
|
headers: { Authorization: localStorage.getItem("token") ?? "" },
|
|
48
42
|
},
|
|
49
43
|
});
|
|
@@ -125,12 +119,81 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
125
119
|
})
|
|
126
120
|
```
|
|
127
121
|
|
|
122
|
+
### API
|
|
123
|
+
|
|
124
|
+
#### SoonOptions
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
// function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>
|
|
128
|
+
// RequestInit is fetch's init options
|
|
129
|
+
type SoonOptions = Omit<RequestInit, "body"> & {
|
|
130
|
+
query?:
|
|
131
|
+
| Record<
|
|
132
|
+
string,
|
|
133
|
+
| string
|
|
134
|
+
| number
|
|
135
|
+
| boolean
|
|
136
|
+
| null
|
|
137
|
+
| undefined
|
|
138
|
+
| (string | number | boolean | null | undefined)[]
|
|
139
|
+
>
|
|
140
|
+
| URLSearchParams;
|
|
141
|
+
params?: Record<string, string | number>;
|
|
142
|
+
timeout?: number;
|
|
143
|
+
body?: RequestInit["body"] | object;
|
|
144
|
+
};
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### parseUrlOptions
|
|
148
|
+
|
|
149
|
+
`parseUrlOptions` source code:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
153
|
+
url: string;
|
|
154
|
+
options?: Options;
|
|
155
|
+
baseURL?: string;
|
|
156
|
+
baseOptions?: Options;
|
|
157
|
+
}) {
|
|
158
|
+
const { url, options, baseURL, baseOptions } = urlOptions;
|
|
159
|
+
//override baseOptions
|
|
160
|
+
const _options = { ...baseOptions, ...options };
|
|
161
|
+
|
|
162
|
+
//signal merge signals by AbortSignal.any
|
|
163
|
+
_options.signal = mergeSignals(
|
|
164
|
+
[baseOptions?.signal, options?.signal],
|
|
165
|
+
_options.timeout
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
//url handled with baseURL , options.query , options.params
|
|
169
|
+
const _url = mergeUrl(url, { ..._options, baseURL });
|
|
170
|
+
|
|
171
|
+
//body auto stringify json body
|
|
172
|
+
let _body = options?.body;
|
|
173
|
+
let is_body_json = isBodyJson(_body);
|
|
174
|
+
_options.body = is_body_json ? JSON.stringify(_body) : _body;
|
|
175
|
+
|
|
176
|
+
//headers merge headers , the same-key header would be override by options.headers
|
|
177
|
+
//if body is json ,then add header "Content-Type": "application/json" }
|
|
178
|
+
const headers = mergeHeaders(
|
|
179
|
+
baseOptions?.headers,
|
|
180
|
+
options?.headers,
|
|
181
|
+
is_body_json ? { "Content-Type": "application/json" } : undefined
|
|
182
|
+
);
|
|
183
|
+
_options.headers = headers;
|
|
184
|
+
|
|
185
|
+
return [_url, _options as Options & { headers: Headers }] as const;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
You can customize your own parse function with the functions exported below:
|
|
190
|
+
`mergeHeaders`, `mergeSignals`, `mergeUrl`, `isBodyJson`
|
|
191
|
+
|
|
128
192
|
### Support Me
|
|
129
193
|
|
|
130
194
|
If you like this library , you can give a **star** on github.
|
|
131
195
|
GitHub: https://github.com/leafio/soon-fetch
|
|
132
196
|
|
|
133
|
-
> I'm looking for a frontend job , expecting an offer or chance for me .
|
|
134
197
|
> Email: leafnote@outlook.com
|
|
135
198
|
|
|
136
199
|
[English](#soon-fetch) | [中文](#soon-fetch-1) | [Installation](#安装-installation)
|
|
@@ -151,11 +214,13 @@ GitHub: https://github.com/leafio/soon-fetch
|
|
|
151
214
|
- [示例](#示例)
|
|
152
215
|
|
|
153
216
|
- [特别功能](#特别功能)
|
|
217
|
+
|
|
154
218
|
- [快捷方法](#快捷方法)
|
|
155
219
|
- [Restful Url 参数自动处理](#restful-url-参数自动处理)
|
|
156
220
|
- [超时](#超时)
|
|
157
221
|
- [快速定义 API](#快速定义-api)
|
|
158
222
|
|
|
223
|
+
- [API](#api-1)
|
|
159
224
|
- [支持一下](#支持一下)
|
|
160
225
|
|
|
161
226
|
### 示例
|
|
@@ -165,19 +230,12 @@ GitHub: https://github.com/leafio/soon-fetch
|
|
|
165
230
|
|
|
166
231
|
```typescript
|
|
167
232
|
const request = <T>(url: string, options?: SoonOptions) => {
|
|
168
|
-
// _url : url 根据 baseURL , options.query , options.params 进行拼接
|
|
169
|
-
// _options: 1. 合并 baseOptions 和 options
|
|
170
|
-
// 2. 合并结果 从 SoonOptions 转换至 原生 fetch options
|
|
171
|
-
// 3. json object 会自动 stringified , 并且添加 header { "Content-Type": "application/json" }
|
|
172
233
|
const [_url, _options] = parseUrlOptions({
|
|
173
234
|
url,
|
|
174
235
|
options,
|
|
175
236
|
baseURL: "/api",
|
|
176
237
|
baseOptions: {
|
|
177
|
-
// 会被 options.timeout 覆盖
|
|
178
238
|
timeout: 20 * 1000,
|
|
179
|
-
// 将与 options.headers 合并
|
|
180
|
-
// 相同key的 header 会被options.headers覆盖
|
|
181
239
|
headers: { Authorization: localStorage.getItem("token") ?? "" },
|
|
182
240
|
},
|
|
183
241
|
});
|
|
@@ -258,12 +316,81 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
258
316
|
})
|
|
259
317
|
```
|
|
260
318
|
|
|
319
|
+
### API
|
|
320
|
+
|
|
321
|
+
#### SoonOptions
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
// function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>
|
|
325
|
+
// RequestInit 为原生 fetch 的 init 选项
|
|
326
|
+
type SoonOptions = Omit<RequestInit, "body"> & {
|
|
327
|
+
query?:
|
|
328
|
+
| Record<
|
|
329
|
+
string,
|
|
330
|
+
| string
|
|
331
|
+
| number
|
|
332
|
+
| boolean
|
|
333
|
+
| null
|
|
334
|
+
| undefined
|
|
335
|
+
| (string | number | boolean | null | undefined)[]
|
|
336
|
+
>
|
|
337
|
+
| URLSearchParams;
|
|
338
|
+
params?: Record<string, string | number>;
|
|
339
|
+
timeout?: number;
|
|
340
|
+
body?: RequestInit["body"] | object;
|
|
341
|
+
};
|
|
342
|
+
```
|
|
343
|
+
#### parseUrlOptions
|
|
344
|
+
|
|
345
|
+
`parseUrlOptions` 源码如下:
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
349
|
+
url: string;
|
|
350
|
+
options?: Options;
|
|
351
|
+
baseURL?: string;
|
|
352
|
+
baseOptions?: Options;
|
|
353
|
+
}) {
|
|
354
|
+
const { url, options, baseURL, baseOptions } = urlOptions;
|
|
355
|
+
// 覆盖 baseOptions
|
|
356
|
+
const _options = { ...baseOptions, ...options };
|
|
357
|
+
|
|
358
|
+
// 以 AbortSignal.any 的方式合并 baseOptions.signal 、 options.signal 、
|
|
359
|
+
// 以及 AbortSignal.timeout( _options.timeout)
|
|
360
|
+
_options.signal = mergeSignals(
|
|
361
|
+
[baseOptions?.signal, options?.signal],
|
|
362
|
+
_options.timeout
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
//根据 baseURL , options.query , options.params 解析出完整的url
|
|
366
|
+
const _url = mergeUrl(url, { ..._options, baseURL });
|
|
367
|
+
|
|
368
|
+
// 自动stringify json-object类的body
|
|
369
|
+
let _body = options?.body;
|
|
370
|
+
let is_body_json = isBodyJson(_body);
|
|
371
|
+
_options.body = is_body_json ? JSON.stringify(_body) : _body;
|
|
372
|
+
|
|
373
|
+
//合并headers, 相同key值的header会被options.headers覆盖
|
|
374
|
+
//当body 为 json ,自动添加 header "Content-Type": "application/json" }
|
|
375
|
+
const headers = mergeHeaders(
|
|
376
|
+
baseOptions?.headers,
|
|
377
|
+
options?.headers,
|
|
378
|
+
is_body_json ? { "Content-Type": "application/json" } : undefined
|
|
379
|
+
);
|
|
380
|
+
_options.headers = headers;
|
|
381
|
+
|
|
382
|
+
return [_url, _options as Options & { headers: Headers }] as const;
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
如有特殊需要,可以根据下方的函数定制你自己的解析函数来替代 `parseUrlOptions`:
|
|
387
|
+
`mergeHeaders`, `mergeSignals`, `mergeUrl`, `isBodyJson`
|
|
388
|
+
|
|
261
389
|
### 支持一下
|
|
262
390
|
|
|
263
391
|
喜欢 soon-fetch 的话 , 在 github 上给个 **star** 吧.
|
|
264
392
|
GitHub: https://github.com/leafio/soon-fetch
|
|
265
393
|
|
|
266
|
-
> 我目前在找前端的工作,有岗位机会的话,可以联系我。
|
|
267
394
|
> Email: leafnote@outlook.com
|
|
268
395
|
|
|
269
396
|
[English](#soon-fetch) | [中文](#soon-fetch-1) | [Installation](#安装-installation)
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const t=t=>{const r=[],e=t.match(/:([^:/\d]+)\/?/g);return e&&e.forEach((t=>{r.push(t.replace(/\//g,"").replace(/:/g,""))})),r},r=(t="")=>t.
|
|
1
|
+
"use strict";const t=t=>{const r=[],e=t.match(/:([^:/\d]+)\/?/g);return e&&e.forEach((t=>{r.push(t.replace(/\//g,"").replace(/:/g,""))})),r},r=(t="")=>t.endsWith("/")?t.slice(0,-1):t,e=(t="")=>t.startsWith("/")?t:"/"+t,n=(t="")=>t.startsWith("http"),a=t=>{if(!t)return[];if(t instanceof URLSearchParams||"string"==typeof t||Array.isArray(t))return Array.from(new URLSearchParams(t).entries());const r=[];return Object.keys(t).forEach((e=>{const n=t[e];(Array.isArray(n)?n:[n]).forEach((t=>{r.push([e,t??""])}))})),r},o=(o,s)=>{const{query:i,params:c,baseURL:f}=s;let p=o.trim();t(o).forEach((t=>{c&&(p=p.replace(":"+t,""+c[t]))}));const[u,h]=p.split("?"),y=new URLSearchParams([...a(h),...a(i)]);let l=((t,a)=>{if(n(t))return t;const o=n(a)?a:e(a);return r(o)+r(e(t))})(u,f);return y.size&&(l=l+"?"+y),l},s=(...t)=>{const r=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,e)=>{r.set(e,t)}))})),r};function i(t,r){const e=(t??[]).filter((t=>!!t));return r&&e.push(AbortSignal.timeout(r)),e.length?AbortSignal.any(e):void 0}function c(t){return!(!t||"object"!=typeof t||(t instanceof Blob||t instanceof ArrayBuffer||t instanceof FormData||t instanceof File||t instanceof DataView||t instanceof URLSearchParams||t instanceof ReadableStream||(r=t,r instanceof Int8Array||r instanceof Uint8Array||r instanceof Uint8ClampedArray||r instanceof Int16Array||r instanceof Uint16Array||r instanceof Int32Array||r instanceof Uint32Array||r instanceof Float32Array||r instanceof Float64Array||r instanceof BigInt64Array||r instanceof BigUint64Array)));var r}const f=["get","post","put","delete","patch"];function p(t,r){const e={};return t.forEach((t=>{e[t]=(e,n)=>r(e,{...n,method:t})})),e}function u(r){return(e,n)=>{const a={},o=!!t(e).length;return f.forEach((t=>{const s=t.toUpperCase();a[s]=()=>(...a)=>{const[s,i]=a,c="get"===t?"query":"body";return r(e,{...n,method:t,params:o?s:void 0,[c]:o?i:s})}})),a}}exports.createShortAPI=u,exports.createShortMethods=p,exports.createSoon=function(t){const r=t;return{request:r,API:u(r),...p([...f,"head","options"],r)}},exports.isBodyJson=c,exports.mergeHeaders=s,exports.mergeSignals=i,exports.mergeUrl=o,exports.parseUrlOptions=function(t){const{url:r,options:e,baseURL:n,baseOptions:a}=t,f={...a,...e};f.signal=i([a?.signal,e?.signal],f.timeout);const p=o(r,{...f,baseURL:n});let u=e?.body,h=c(u);f.body=h?JSON.stringify(u):u;const y=s(a?.headers,e?.headers,h?{"Content-Type":"application/json"}:void 0);return f.headers=y,[p,f]};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
type SoonOptions = RequestInit & {
|
|
2
|
-
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
3
|
-
params?: Record<string, string | number>;
|
|
4
|
-
timeout?: number;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
type
|
|
8
|
-
type
|
|
9
|
-
type
|
|
10
|
-
type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
declare const
|
|
19
|
-
declare function
|
|
20
|
-
declare function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
type SoonOptions = Omit<RequestInit, "body"> & {
|
|
2
|
+
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
3
|
+
params?: Record<string, string | number>;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
body?: RequestInit["body"] | object;
|
|
6
|
+
};
|
|
7
|
+
type GetUrlKey<Url> = Url extends `${string}/:${infer Key}/${infer Right}` ? `${Key}` | GetUrlKey<`/${Right}`> : Url extends `${string}/:${infer Key}` ? `${Key}` : never;
|
|
8
|
+
type OptionParams<Args> = NonNullable<Args> extends never ? [] : keyof NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [params: Args] : [params?: Args];
|
|
9
|
+
type OptionQuery<Args> = NonNullable<Args> extends never ? [] : keyof NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? Partial<Args> extends Args ? [query?: Args] : [query: Args] : [query?: Args];
|
|
10
|
+
type OptionBody<Args> = NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [body: Args] : [body?: Args];
|
|
11
|
+
type Tuple2Union<T> = T extends [infer T1, infer T2, ...infer R] ? T1 | T2 | Tuple2Union<R> : T extends [infer T_Only] ? T_Only : never;
|
|
12
|
+
|
|
13
|
+
declare const mergeUrl: (url: string, config: {
|
|
14
|
+
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
15
|
+
params?: Record<string, string | number>;
|
|
16
|
+
baseURL?: string;
|
|
17
|
+
}) => string;
|
|
18
|
+
declare const mergeHeaders: (...headersList: (HeadersInit | undefined)[]) => Headers;
|
|
19
|
+
declare function mergeSignals(signals?: (AbortSignal | null | undefined)[], timeout?: number): AbortSignal | undefined;
|
|
20
|
+
declare function isBodyJson(body: any): boolean;
|
|
21
|
+
declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
22
|
+
url: string;
|
|
23
|
+
options?: Options;
|
|
24
|
+
baseURL?: string;
|
|
25
|
+
baseOptions?: Options;
|
|
26
|
+
}): readonly [string, Options & {
|
|
27
|
+
headers: Headers;
|
|
28
|
+
body?: BodyInit | null;
|
|
29
|
+
}];
|
|
30
|
+
declare function createSoon<T extends (url: string, options?: SoonOptions) => Promise<any>>(requestFun: T): {
|
|
31
|
+
options: T;
|
|
32
|
+
get: T;
|
|
33
|
+
post: T;
|
|
34
|
+
put: T;
|
|
35
|
+
delete: T;
|
|
36
|
+
patch: T;
|
|
37
|
+
head: T;
|
|
38
|
+
request: T;
|
|
39
|
+
API: <Url extends string>(url: Url, options?: Parameters<T>[1] | undefined) => Record<"GET", <Req = undefined, Res = Awaited<ReturnType<T>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionQuery<Req>]) => Promise<Res>> & Record<"POST" | "PATCH" | "DELETE" | "PUT", <Req = undefined, Res = Awaited<ReturnType<T>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionBody<Req>]) => Promise<Res>>;
|
|
40
|
+
};
|
|
41
|
+
declare function createShortMethods<Methods extends string[], RequestFun extends <T>(url: string, options?: {
|
|
42
|
+
method?: string;
|
|
43
|
+
}) => Promise<any>>(methods: Methods, requestFun: RequestFun): Record<Tuple2Union<Methods>, typeof requestFun>;
|
|
44
|
+
declare function createShortAPI<requestFun extends <T>(url: string, options?: SoonOptions) => Promise<any>>(requestFun: requestFun): <Url extends string>(url: Url, options?: Parameters<requestFun>[1]) => Record<"GET", <Req = undefined, Res = Awaited<ReturnType<requestFun>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionQuery<Req>]) => Promise<Res>> & Record<"POST" | "PATCH" | "DELETE" | "PUT", <Req = undefined, Res = Awaited<ReturnType<requestFun>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionBody<Req>]) => Promise<Res>>;
|
|
45
|
+
|
|
46
|
+
export { type SoonOptions, createShortAPI, createShortMethods, createSoon, isBodyJson, mergeHeaders, mergeSignals, mergeUrl, parseUrlOptions };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const t=t=>{const n=[],r=t.match(/:([^:/\d]+)\/?/g);return r&&r.forEach((t=>{n.push(t.replace(/\//g,"").replace(/:/g,""))})),n},n=(t="")=>t.
|
|
1
|
+
const t=t=>{const n=[],r=t.match(/:([^:/\d]+)\/?/g);return r&&r.forEach((t=>{n.push(t.replace(/\//g,"").replace(/:/g,""))})),n},n=(t="")=>t.endsWith("/")?t.slice(0,-1):t,r=(t="")=>t.startsWith("/")?t:"/"+t,e=(t="")=>t.startsWith("http"),a=t=>{if(!t)return[];if(t instanceof URLSearchParams||"string"==typeof t||Array.isArray(t))return Array.from(new URLSearchParams(t).entries());const n=[];return Object.keys(t).forEach((r=>{const e=t[r];(Array.isArray(e)?e:[e]).forEach((t=>{n.push([r,t??""])}))})),n},o=(o,s)=>{const{query:i,params:c,baseURL:f}=s;let u=o.trim();t(o).forEach((t=>{c&&(u=u.replace(":"+t,""+c[t]))}));const[h,y]=u.split("?"),l=new URLSearchParams([...a(y),...a(i)]);let p=((t,a)=>{if(e(t))return t;const o=e(a)?a:r(a);return n(o)+n(r(t))})(h,f);return l.size&&(p=p+"?"+l),p},s=(...t)=>{const n=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,r)=>{n.set(r,t)}))})),n};function i(t,n){const r=(t??[]).filter((t=>!!t));return n&&r.push(AbortSignal.timeout(n)),r.length?AbortSignal.any(r):void 0}function c(t){return!(!t||"object"!=typeof t||(t instanceof Blob||t instanceof ArrayBuffer||t instanceof FormData||t instanceof File||t instanceof DataView||t instanceof URLSearchParams||t instanceof ReadableStream||(n=t,n instanceof Int8Array||n instanceof Uint8Array||n instanceof Uint8ClampedArray||n instanceof Int16Array||n instanceof Uint16Array||n instanceof Int32Array||n instanceof Uint32Array||n instanceof Float32Array||n instanceof Float64Array||n instanceof BigInt64Array||n instanceof BigUint64Array)));var n}function f(t){const{url:n,options:r,baseURL:e,baseOptions:a}=t,f={...a,...r};f.signal=i([a?.signal,r?.signal],f.timeout);const u=o(n,{...f,baseURL:e});let h=r?.body,y=c(h);f.body=y?JSON.stringify(h):h;const l=s(a?.headers,r?.headers,y?{"Content-Type":"application/json"}:void 0);return f.headers=l,[u,f]}const u=["get","post","put","delete","patch"];function h(t){const n=t;return{request:n,API:l(n),...y([...u,"head","options"],n)}}function y(t,n){const r={};return t.forEach((t=>{r[t]=(r,e)=>n(r,{...e,method:t})})),r}function l(n){return(r,e)=>{const a={},o=!!t(r).length;return u.forEach((t=>{const s=t.toUpperCase();a[s]=()=>(...a)=>{const[s,i]=a,c="get"===t?"query":"body";return n(r,{...e,method:t,params:o?s:void 0,[c]:o?i:s})}})),a}}export{l as createShortAPI,y as createShortMethods,h as createSoon,c as isBodyJson,s as mergeHeaders,i as mergeSignals,o as mergeUrl,f as parseUrlOptions};
|