soon-fetch 2.1.0 → 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 +52 -6
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -121,6 +121,29 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
121
121
|
|
|
122
122
|
### API
|
|
123
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
|
+
|
|
124
147
|
#### parseUrlOptions
|
|
125
148
|
|
|
126
149
|
`parseUrlOptions` source code:
|
|
@@ -295,6 +318,28 @@ soon.get(url, { timeout: 1000 * 20 });
|
|
|
295
318
|
|
|
296
319
|
### API
|
|
297
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
|
+
```
|
|
298
343
|
#### parseUrlOptions
|
|
299
344
|
|
|
300
345
|
`parseUrlOptions` 源码如下:
|
|
@@ -307,25 +352,26 @@ function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
|
307
352
|
baseOptions?: Options;
|
|
308
353
|
}) {
|
|
309
354
|
const { url, options, baseURL, baseOptions } = urlOptions;
|
|
310
|
-
//
|
|
355
|
+
// 覆盖 baseOptions
|
|
311
356
|
const _options = { ...baseOptions, ...options };
|
|
312
357
|
|
|
313
|
-
//
|
|
358
|
+
// 以 AbortSignal.any 的方式合并 baseOptions.signal 、 options.signal 、
|
|
359
|
+
// 以及 AbortSignal.timeout( _options.timeout)
|
|
314
360
|
_options.signal = mergeSignals(
|
|
315
361
|
[baseOptions?.signal, options?.signal],
|
|
316
362
|
_options.timeout
|
|
317
363
|
);
|
|
318
364
|
|
|
319
|
-
|
|
365
|
+
//根据 baseURL , options.query , options.params 解析出完整的url
|
|
320
366
|
const _url = mergeUrl(url, { ..._options, baseURL });
|
|
321
367
|
|
|
322
|
-
//
|
|
368
|
+
// 自动stringify json-object类的body
|
|
323
369
|
let _body = options?.body;
|
|
324
370
|
let is_body_json = isBodyJson(_body);
|
|
325
371
|
_options.body = is_body_json ? JSON.stringify(_body) : _body;
|
|
326
372
|
|
|
327
|
-
|
|
328
|
-
|
|
373
|
+
//合并headers, 相同key值的header会被options.headers覆盖
|
|
374
|
+
//当body 为 json ,自动添加 header "Content-Type": "application/json" }
|
|
329
375
|
const headers = mergeHeaders(
|
|
330
376
|
baseOptions?.headers,
|
|
331
377
|
options?.headers,
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const t=t=>{const
|
|
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,7 +1,8 @@
|
|
|
1
|
-
type SoonOptions = RequestInit & {
|
|
1
|
+
type SoonOptions = Omit<RequestInit, "body"> & {
|
|
2
2
|
query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
|
|
3
3
|
params?: Record<string, string | number>;
|
|
4
4
|
timeout?: number;
|
|
5
|
+
body?: RequestInit["body"] | object;
|
|
5
6
|
};
|
|
6
7
|
type GetUrlKey<Url> = Url extends `${string}/:${infer Key}/${infer Right}` ? `${Key}` | GetUrlKey<`/${Right}`> : Url extends `${string}/:${infer Key}` ? `${Key}` : never;
|
|
7
8
|
type OptionParams<Args> = NonNullable<Args> extends never ? [] : keyof NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [params: Args] : [params?: Args];
|
|
@@ -24,6 +25,7 @@ declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
|
|
|
24
25
|
baseOptions?: Options;
|
|
25
26
|
}): readonly [string, Options & {
|
|
26
27
|
headers: Headers;
|
|
28
|
+
body?: BodyInit | null;
|
|
27
29
|
}];
|
|
28
30
|
declare function createSoon<T extends (url: string, options?: SoonOptions) => Promise<any>>(requestFun: T): {
|
|
29
31
|
options: T;
|
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};
|