soon-fetch 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -225
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +46 -45
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
> - ⭐ rapid define a request api
|
|
11
11
|
> - ⌛ timeout disconnect
|
|
12
12
|
> - 🔤 automatic parse or serialization of JSON
|
|
13
|
-
> - 📏 .min size less than **
|
|
13
|
+
> - 📏 .min size less than **3K**, smaller after zip
|
|
14
14
|
> - 💡 smart type tips with Typescript
|
|
15
15
|
|
|
16
16
|
- [Example](#example)
|
|
@@ -20,10 +20,6 @@
|
|
|
20
20
|
- [Restful Url Params](#restful-url-params)
|
|
21
21
|
- [Timeout](#timeout)
|
|
22
22
|
- [Rapid Define APIs](#rapid-define-apis)
|
|
23
|
-
- [API Reference](#api-reference)
|
|
24
|
-
- [Create Instance](#create-instance)
|
|
25
|
-
- [Request](#request)
|
|
26
|
-
- [Response](#response)
|
|
27
23
|
- [Support Me](#support-me)
|
|
28
24
|
|
|
29
25
|
### Example
|
|
@@ -32,18 +28,30 @@
|
|
|
32
28
|
> [github: soon-admin-react-nextjs ](https://github.com/leafio/soon-admin-react-nextjs)
|
|
33
29
|
|
|
34
30
|
```typescript
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
import { createSoon, parseUrlOptions, type SoonOptions } from "soon-fetch";
|
|
32
|
+
|
|
33
|
+
const request = (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
|
+
const [_url, _options] = parseUrlOptions({
|
|
39
|
+
url,
|
|
40
|
+
options,
|
|
41
|
+
baseURL: "/api",
|
|
42
|
+
baseOptions: {
|
|
43
|
+
// would override by options.timeout
|
|
44
|
+
timeout: 20 * 1000,
|
|
45
|
+
// would merged with options.headers
|
|
46
|
+
// the same-key header would override by options.headers
|
|
47
|
+
headers: { Authorization: localStorage.getItem("token") ?? "" },
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return fetch(_url, _options).then((res) => res.json());
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const soon = createSoon(request);
|
|
47
55
|
|
|
48
56
|
/** GET */
|
|
49
57
|
soon.get("/user?id=123");
|
|
@@ -117,106 +125,13 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
117
125
|
})
|
|
118
126
|
```
|
|
119
127
|
|
|
120
|
-
### API Reference
|
|
121
|
-
|
|
122
|
-
##### Create Instance
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
import { createSoon } from "soon";
|
|
126
|
-
|
|
127
|
-
declare function createSoon<Options extends SoonOptions = SoonOptions>(
|
|
128
|
-
soonInit?: SoonInit<Options>
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// options would overwritten by request level options ,but the headers will be merged
|
|
132
|
-
export type SoonInit<Options> = {
|
|
133
|
-
//**url prefix */
|
|
134
|
-
baseURL?: string;
|
|
135
|
-
/**the fetch http options */
|
|
136
|
-
options?: () => Options;
|
|
137
|
-
/** can use return a new fetch request instead*/
|
|
138
|
-
fetching?: (
|
|
139
|
-
url: string,
|
|
140
|
-
options: Options & { headers: Headers }
|
|
141
|
-
) => Promise<any>;
|
|
142
|
-
};
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
##### Request
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
soon.request(url[,options])
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Request data can choose `query` `params` `body` for easy specification
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
type SoonOptions = {
|
|
155
|
-
/** url search params like `api/info?name=yes` {name:"yes"} passed here*/
|
|
156
|
-
query?:
|
|
157
|
-
| Record<
|
|
158
|
-
string,
|
|
159
|
-
string | number | boolean | string[] | number[] | null | undefined
|
|
160
|
-
>
|
|
161
|
-
| URLSearchParams;
|
|
162
|
-
/** url rest params like `api/info/:id` {id:1} passed here*/
|
|
163
|
-
params?: Record<string, string | number>;
|
|
164
|
-
/** unit ms */
|
|
165
|
-
timeout?: number;
|
|
166
|
-
/***** vanilla fetch props *****/
|
|
167
|
-
//body can pass json without stringified
|
|
168
|
-
body?: any;
|
|
169
|
-
signal?: AbortSignal;
|
|
170
|
-
method?:
|
|
171
|
-
| "get"
|
|
172
|
-
| "GET"
|
|
173
|
-
| "delete"
|
|
174
|
-
| "DELETE"
|
|
175
|
-
| "head"
|
|
176
|
-
| "HEAD"
|
|
177
|
-
| "options"
|
|
178
|
-
| "OPTIONS"
|
|
179
|
-
| "post"
|
|
180
|
-
| "POST"
|
|
181
|
-
| "put"
|
|
182
|
-
| "PUT"
|
|
183
|
-
| "patch"
|
|
184
|
-
| "PATCH"
|
|
185
|
-
| "purge"
|
|
186
|
-
| "PURGE"
|
|
187
|
-
| "link"
|
|
188
|
-
| "LINK"
|
|
189
|
-
| "unlink"
|
|
190
|
-
| "UNLINK";
|
|
191
|
-
mode?: "cors" | "no-cors" | "same-origin";
|
|
192
|
-
cache?: "default" | "no-cache" | "reload" | "force-cache" | "only-if-cached";
|
|
193
|
-
credentials?: "include" | "same-origin" | "omit";
|
|
194
|
-
headers?: Headers;
|
|
195
|
-
redirect?: "manual" | "follow" | "error";
|
|
196
|
-
referrerPolicy?:
|
|
197
|
-
| "no-referrer"
|
|
198
|
-
| "no-referrer-when-downgrade"
|
|
199
|
-
| "origin"
|
|
200
|
-
| "origin-when-cross-origin"
|
|
201
|
-
| "same-origin"
|
|
202
|
-
| "strict-origin"
|
|
203
|
-
| "strict-origin-when-cross-origin"
|
|
204
|
-
| "unsafe-url";
|
|
205
|
-
integrity?: string;
|
|
206
|
-
};
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
##### Response
|
|
210
|
-
|
|
211
|
-
Default : return raw fetch Response , you can customize it in `fetching` params of `createSoon`
|
|
212
|
-
|
|
213
128
|
### Support Me
|
|
214
129
|
|
|
215
130
|
If you like this library , you can give a **star** on github.
|
|
216
131
|
GitHub: https://github.com/leafio/soon-fetch
|
|
217
132
|
|
|
218
|
-
> I'm looking for a frontend job
|
|
219
|
-
Email: leafnote@outlook.com
|
|
133
|
+
> I'm looking for a frontend job , expecting an offer or chance for me .
|
|
134
|
+
> Email: leafnote@outlook.com
|
|
220
135
|
|
|
221
136
|
[English](#soon-fetch) | [中文](#soon-fetch-1) | [Installation](#安装-installation)
|
|
222
137
|
|
|
@@ -224,13 +139,13 @@ Email: leafnote@outlook.com
|
|
|
224
139
|
|
|
225
140
|
#### soon-fetch
|
|
226
141
|
|
|
227
|
-
**极轻量的请求库,不到
|
|
142
|
+
**极轻量的请求库,不到 3K**
|
|
228
143
|
|
|
229
144
|
> - 🌐 自动解析 rest Url 的参数
|
|
230
145
|
> - ⭐ 快捷定义请求 api
|
|
231
146
|
> - ⌛ 超时断开
|
|
232
147
|
> - 🔤 自动处理 JSON
|
|
233
|
-
> - 📏 不到 **
|
|
148
|
+
> - 📏 不到 **3K** , zip 后会更小
|
|
234
149
|
> - 💡 用 typescript 有智能类型提醒
|
|
235
150
|
|
|
236
151
|
- [示例](#示例)
|
|
@@ -240,11 +155,6 @@ Email: leafnote@outlook.com
|
|
|
240
155
|
- [Restful Url 参数自动处理](#restful-url-参数自动处理)
|
|
241
156
|
- [超时](#超时)
|
|
242
157
|
- [快速定义 API](#快速定义-api)
|
|
243
|
-
- [API 参考](#api参考)
|
|
244
|
-
|
|
245
|
-
- [创建实例](#创建实例)
|
|
246
|
-
- [请求](#请求)
|
|
247
|
-
- [响应](#响应)
|
|
248
158
|
|
|
249
159
|
- [支持一下](#支持一下)
|
|
250
160
|
|
|
@@ -254,18 +164,28 @@ Email: leafnote@outlook.com
|
|
|
254
164
|
> [github: soon-admin-react-nextjs ](https://github.com/leafio/soon-admin-react-nextjs)
|
|
255
165
|
|
|
256
166
|
```typescript
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
167
|
+
const request = (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
|
+
const [_url, _options] = parseUrlOptions({
|
|
173
|
+
url,
|
|
174
|
+
options,
|
|
175
|
+
baseURL: "/api",
|
|
176
|
+
baseOptions: {
|
|
177
|
+
// 会被 options.timeout 覆盖
|
|
178
|
+
timeout: 20 * 1000,
|
|
179
|
+
// 将与 options.headers 合并
|
|
180
|
+
// 相同key的 header 会被options.headers覆盖
|
|
181
|
+
headers: { Authorization: localStorage.getItem("token") ?? "" },
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return fetch(_url, _options).then((res) => res.json());
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const soon = createSoon(request);
|
|
269
189
|
|
|
270
190
|
/** GET */
|
|
271
191
|
soon.get("/user?id=123");
|
|
@@ -338,105 +258,12 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
338
258
|
})
|
|
339
259
|
```
|
|
340
260
|
|
|
341
|
-
### API 参考
|
|
342
|
-
|
|
343
|
-
##### 创建实例
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
import { createSoon } from "soon";
|
|
347
|
-
|
|
348
|
-
declare function createSoon<Options extends SoonOptions = SoonOptions>(
|
|
349
|
-
soonInit?: SoonInit<Options>
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
// 实例级options会被请求级options覆盖,但headers仅同key的被覆盖,其他合并
|
|
353
|
-
export type SoonInit<Options> = {
|
|
354
|
-
baseURL?: string;
|
|
355
|
-
//默认的options
|
|
356
|
-
options?: () => Options;
|
|
357
|
-
//可返回自定义的fetch请求
|
|
358
|
-
fetching?: (
|
|
359
|
-
url: string,
|
|
360
|
-
options: Options & { headers: Headers }
|
|
361
|
-
) => Promise<any>;
|
|
362
|
-
};
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
##### 请求
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
soon.request(url[,options])
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
请求数据可以选择 _`query`_ _`params`_ _`body`_ ,易于传递。
|
|
372
|
-
|
|
373
|
-
```typescript
|
|
374
|
-
type SoonOptions = {
|
|
375
|
-
/** url ?后的参数 `api/info?name=yes` 传递 {name:"yes"}*/
|
|
376
|
-
query?:
|
|
377
|
-
| Record<
|
|
378
|
-
string,
|
|
379
|
-
string | number | boolean | string[] | number[] | null | undefined
|
|
380
|
-
>
|
|
381
|
-
| URLSearchParams;
|
|
382
|
-
/** rest风格url的请求参数 `api/info/:id` 传递 {id:1}*/
|
|
383
|
-
params?: Record<string, string | number>;
|
|
384
|
-
/** unit 毫秒 */
|
|
385
|
-
timeout?: number;
|
|
386
|
-
|
|
387
|
-
/*** 原生fetch 参数*/
|
|
388
|
-
//可直接传递JSON而不必stringified
|
|
389
|
-
body?: any;
|
|
390
|
-
signal?: AbortSignal;
|
|
391
|
-
method?:
|
|
392
|
-
| "get"
|
|
393
|
-
| "GET"
|
|
394
|
-
| "delete"
|
|
395
|
-
| "DELETE"
|
|
396
|
-
| "head"
|
|
397
|
-
| "HEAD"
|
|
398
|
-
| "options"
|
|
399
|
-
| "OPTIONS"
|
|
400
|
-
| "post"
|
|
401
|
-
| "POST"
|
|
402
|
-
| "put"
|
|
403
|
-
| "PUT"
|
|
404
|
-
| "patch"
|
|
405
|
-
| "PATCH"
|
|
406
|
-
| "purge"
|
|
407
|
-
| "PURGE"
|
|
408
|
-
| "link"
|
|
409
|
-
| "LINK"
|
|
410
|
-
| "unlink"
|
|
411
|
-
| "UNLINK";
|
|
412
|
-
mode?: "cors" | "no-cors" | "same-origin";
|
|
413
|
-
cache?: "default" | "no-cache" | "reload" | "force-cache" | "only-if-cached";
|
|
414
|
-
credentials?: "include" | "same-origin" | "omit";
|
|
415
|
-
headers?: Headers;
|
|
416
|
-
redirect?: "manual" | "follow" | "error";
|
|
417
|
-
referrerPolicy?:
|
|
418
|
-
| "no-referrer"
|
|
419
|
-
| "no-referrer-when-downgrade"
|
|
420
|
-
| "origin"
|
|
421
|
-
| "origin-when-cross-origin"
|
|
422
|
-
| "same-origin"
|
|
423
|
-
| "strict-origin"
|
|
424
|
-
| "strict-origin-when-cross-origin"
|
|
425
|
-
| "unsafe-url";
|
|
426
|
-
integrity?: string;
|
|
427
|
-
};
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
##### 响应
|
|
431
|
-
|
|
432
|
-
默认为原生 fetch 的 Response ,可在 `createSoon` 的 `fetching` 里自定义返回结果
|
|
433
|
-
|
|
434
261
|
### 支持一下
|
|
435
262
|
|
|
436
263
|
喜欢 soon-fetch 的话 , 在 github 上给个 **star** 吧.
|
|
437
264
|
GitHub: https://github.com/leafio/soon-fetch
|
|
438
265
|
|
|
439
|
-
>
|
|
266
|
+
> 我目前在找前端的工作,有岗位机会的话,可以联系我。
|
|
440
267
|
> Email: leafnote@outlook.com
|
|
441
268
|
|
|
442
269
|
[English](#soon-fetch) | [中文](#soon-fetch-1) | [Installation](#安装-installation)
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const 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.startsWith("http"),e=(t="")=>r(t)?t:((t="")=>{let r=t;return t&&(r=((t="")=>t.endsWith("/")?t.slice(0,-1):t)(r),t.startsWith("/")||(r="/"+r)),r})(t),n=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},a=(a,o)=>{const{query:s,params:i,baseURL:c}=o;let f=a.trim();t(a).forEach((t=>{i&&(f=f.replace(":"+t,""+i[t]))}));const[p,u]=f.split("?"),h=new URLSearchParams([...n(u),...n(s)]);let y=((t,n)=>{let a=e(t);return r(a)||(a=e(n)+a),a})(p,c);return h.size&&(y=y+"?"+h),y},o=(...t)=>{const r=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,e)=>{r.set(e,t)}))})),r},s=(t,r)=>{const e=[];return t&&e.push(AbortSignal.timeout(t)),r&&e.push(r),e.length?AbortSignal.any(e):void 0};function i(t){let r=!1,e=t;var n;return e&&"object"==typeof e&&!(e instanceof Blob||e instanceof ArrayBuffer||e instanceof FormData||e instanceof File||e instanceof DataView||e instanceof URLSearchParams||e instanceof ReadableStream||(n=e,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))&&(r=!0,e=JSON.stringify(e)),[e,r]}const c=["get","post","put","delete","patch"];function f(t,r){const e={};return t.forEach((t=>{e[t]=(e,n)=>r(e,{...n,method:t})})),e}function p(r){return(e,n)=>{const a={},o=!!t(e).length;return c.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=p,exports.createShortMethods=f,exports.createSoon=function(t){const r=t;return{request:r,API:p(r),...f([...c,"head","options"],r)}},exports.mergeHeaders=o,exports.mergeSignal=s,exports.mergeUrl=a,exports.parseUrlOptions=function(t){const{url:r,options:e,baseURL:n,baseOptions:c}=t,f={...c,...e};f.signal=s(f.timeout,f.signal);const p=a(r,{...f,baseURL:n}),[u,h]=i(f.body);f.body=u;const y=o(c?.headers,e?.headers,h?{"Content-Type":"application/json"}:void 0);return f.headers=y,[p,f]},exports.stringifyBody=i;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
|
-
type SoonOptions = {
|
|
2
|
-
query?: Record<string, string | number | boolean | string
|
|
3
|
-
params?: Record<string, string | number>;
|
|
4
|
-
timeout?: number;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
baseURL?: string;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
options:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
+
type GetUrlKey<Url> = Url extends `${string}/:${infer Key}/${infer Right}` ? `${Key}` | GetUrlKey<`/${Right}`> : Url extends `${string}/:${infer Key}` ? `${Key}` : never;
|
|
7
|
+
type OptionParams<Args> = NonNullable<Args> extends never ? [] : keyof NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [params: Args] : [params?: Args];
|
|
8
|
+
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];
|
|
9
|
+
type OptionBody<Args> = NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [body: Args] : [body?: Args];
|
|
10
|
+
type Tuple2Union<T> = T extends [infer T1, infer T2, ...infer R] ? T1 | T2 | Tuple2Union<R> : T extends [infer T_Only] ? T_Only : never;
|
|
11
|
+
type TupleLast<T> = Required<T> extends [infer First, ...infer Rest] ? Rest : never;
|
|
12
|
+
type TupleFirst<T> = Required<T> extends [...infer Rest, infer Last] ? Rest : never;
|
|
13
|
+
|
|
14
|
+
declare const mergeUrl: (url: string, config: {
|
|
15
|
+
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
16
|
+
params?: Record<string, string | number>;
|
|
17
|
+
baseURL?: string;
|
|
18
|
+
}) => string;
|
|
19
|
+
declare const mergeHeaders: (...headersList: (HeadersInit | undefined)[]) => Headers;
|
|
20
|
+
declare const mergeSignal: (timeout?: number, signal?: AbortSignal | null) => AbortSignal | undefined;
|
|
21
|
+
declare function stringifyBody(body?: any): [body: any, isBodyJson: boolean];
|
|
22
|
+
declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
23
|
+
url: string;
|
|
24
|
+
options?: Options;
|
|
25
|
+
baseURL?: string;
|
|
26
|
+
baseOptions?: Options;
|
|
27
|
+
}): readonly [string, Options & {
|
|
28
|
+
headers: Headers;
|
|
29
|
+
}];
|
|
30
|
+
declare function createSoon<T extends (url: string, options?: SoonOptions) => Promise<any>>(requestFun: T): {
|
|
31
|
+
options: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
32
|
+
get: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
33
|
+
post: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
34
|
+
put: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
35
|
+
delete: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
36
|
+
patch: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
37
|
+
head: T extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never;
|
|
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_1 = Awaited<ReturnType<T>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionBody<Req>]) => Promise<Res_1>>;
|
|
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 extends (...args: infer P) => infer R ? (...args: [...TupleFirst<P>, ...Partial<TupleLast<P>>]) => R : never>;
|
|
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_1 = Awaited<ReturnType<requestFun>>>() => (...arg: [...OptionParams<{ [key in GetUrlKey<Url>]: string | number; }>, ...OptionBody<Req>]) => Promise<Res_1>>;
|
|
45
|
+
|
|
46
|
+
export { type SoonOptions, createShortAPI, createShortMethods, createSoon, mergeHeaders, mergeSignal, mergeUrl, parseUrlOptions, stringifyBody };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const 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.startsWith("http"),r=(t="")=>n(t)?t:((t="")=>{let n=t;return t&&(n=((t="")=>t.endsWith("/")?t.slice(0,-1):t)(n),t.startsWith("/")||(n="/"+n)),n})(t),e=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},a=(a,o)=>{const{query:s,params:c,baseURL:i}=o;let f=a.trim();t(a).forEach((t=>{c&&(f=f.replace(":"+t,""+c[t]))}));const[u,h]=f.split("?"),y=new URLSearchParams([...e(h),...e(s)]);let p=((t,e)=>{let a=r(t);return n(a)||(a=r(e)+a),a})(u,i);return y.size&&(p=p+"?"+y),p},o=(...t)=>{const n=new Headers;return t.forEach((t=>{t&&new Headers(t).forEach(((t,r)=>{n.set(r,t)}))})),n},s=(t,n)=>{const r=[];return t&&r.push(AbortSignal.timeout(t)),n&&r.push(n),r.length?AbortSignal.any(r):void 0};function c(t){let n=!1,r=t;var e;return r&&"object"==typeof r&&!(r instanceof Blob||r instanceof ArrayBuffer||r instanceof FormData||r instanceof File||r instanceof DataView||r instanceof URLSearchParams||r instanceof ReadableStream||(e=r,e instanceof Int8Array||e instanceof Uint8Array||e instanceof Uint8ClampedArray||e instanceof Int16Array||e instanceof Uint16Array||e instanceof Int32Array||e instanceof Uint32Array||e instanceof Float32Array||e instanceof Float64Array||e instanceof BigInt64Array||e instanceof BigUint64Array))&&(n=!0,r=JSON.stringify(r)),[r,n]}function i(t){const{url:n,options:r,baseURL:e,baseOptions:i}=t,f={...i,...r};f.signal=s(f.timeout,f.signal);const u=a(n,{...f,baseURL:e}),[h,y]=c(f.body);f.body=h;const p=o(i?.headers,r?.headers,y?{"Content-Type":"application/json"}:void 0);return f.headers=p,[u,f]}const f=["get","post","put","delete","patch"];function u(t){const n=t;return{request:n,API:y(n),...h([...f,"head","options"],n)}}function h(t,n){const r={};return t.forEach((t=>{r[t]=(r,e)=>n(r,{...e,method:t})})),r}function y(n){return(r,e)=>{const a={},o=!!t(r).length;return f.forEach((t=>{const s=t.toUpperCase();a[s]=()=>(...a)=>{const[s,c]=a,i="get"===t?"query":"body";return n(r,{...e,method:t,params:o?s:void 0,[i]:o?c:s})}})),a}}export{y as createShortAPI,h as createShortMethods,u as createSoon,o as mergeHeaders,s as mergeSignal,a as mergeUrl,i as parseUrlOptions,c as stringifyBody};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "soon-fetch",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "a
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "a 3Kb request lib alternative to axios",
|
|
5
5
|
"homepage": "https://github.com/leafio/soon-fetch",
|
|
6
6
|
"main": "./dist/index.cjs.js",
|
|
7
7
|
"module": "/dist/index.js",
|