soon-fetch 2.0.0 → 2.0.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 CHANGED
@@ -30,7 +30,7 @@
30
30
  ```typescript
31
31
  import { createSoon, parseUrlOptions, type SoonOptions } from "soon-fetch";
32
32
 
33
- const request = (url: string, options?: SoonOptions) => {
33
+ const request = <T>(url: string, options?: SoonOptions) => {
34
34
  // _url : url handled with baseURL , options.query , options.params
35
35
  // _options: 1. merge baseOptions and options,
36
36
  // 2. transfer merged options from SoonOptions to raw fetch options
@@ -48,7 +48,7 @@ const request = (url: string, options?: SoonOptions) => {
48
48
  },
49
49
  });
50
50
 
51
- return fetch(_url, _options).then((res) => res.json());
51
+ return fetch(_url, _options).then((res) => res.json() as T);
52
52
  };
53
53
 
54
54
  const soon = createSoon(request);
@@ -164,7 +164,7 @@ GitHub: https://github.com/leafio/soon-fetch
164
164
  > [github: soon-admin-react-nextjs ](https://github.com/leafio/soon-admin-react-nextjs)
165
165
 
166
166
  ```typescript
167
- const request = (url: string, options?: SoonOptions) => {
167
+ const request = <T>(url: string, options?: SoonOptions) => {
168
168
  // _url : url 根据 baseURL , options.query , options.params 进行拼接
169
169
  // _options: 1. 合并 baseOptions 和 options
170
170
  // 2. 合并结果 从 SoonOptions 转换至 原生 fetch options
@@ -182,7 +182,7 @@ const request = (url: string, options?: SoonOptions) => {
182
182
  },
183
183
  });
184
184
 
185
- return fetch(_url, _options).then((res) => res.json());
185
+ return fetch(_url, _options).then((res) => res.json() as T);
186
186
  };
187
187
 
188
188
  const soon = createSoon(request);
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.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;
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=(r??[]).filter((t=>!!t));return t&&e.push(AbortSignal.timeout(t)),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.mergeSignals=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
@@ -8,8 +8,6 @@ type OptionParams<Args> = NonNullable<Args> extends never ? [] : keyof NonNullab
8
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
9
  type OptionBody<Args> = NonNullable<Args> extends never ? [] : Exclude<Args, NonNullable<Args>> extends never ? [body: Args] : [body?: Args];
10
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
11
 
14
12
  declare const mergeUrl: (url: string, config: {
15
13
  query?: Record<string, string | number | boolean | null | undefined | (string | number | boolean | null | undefined)[]> | URLSearchParams;
@@ -17,7 +15,7 @@ declare const mergeUrl: (url: string, config: {
17
15
  baseURL?: string;
18
16
  }) => string;
19
17
  declare const mergeHeaders: (...headersList: (HeadersInit | undefined)[]) => Headers;
20
- declare const mergeSignal: (timeout?: number, signal?: AbortSignal | null) => AbortSignal | undefined;
18
+ declare const mergeSignals: (timeout?: number, signals?: (AbortSignal | null | undefined)[]) => AbortSignal | undefined;
21
19
  declare function stringifyBody(body?: any): [body: any, isBodyJson: boolean];
22
20
  declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
23
21
  url: string;
@@ -28,19 +26,19 @@ declare function parseUrlOptions<Options extends SoonOptions>(urlOptions: {
28
26
  headers: Headers;
29
27
  }];
30
28
  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;
29
+ options: T;
30
+ get: T;
31
+ post: T;
32
+ put: T;
33
+ delete: T;
34
+ patch: T;
35
+ head: T;
38
36
  request: T;
39
37
  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
38
  };
41
39
  declare function createShortMethods<Methods extends string[], RequestFun extends <T>(url: string, options?: {
42
40
  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>;
41
+ }) => Promise<any>>(methods: Methods, requestFun: RequestFun): Record<Tuple2Union<Methods>, typeof requestFun>;
44
42
  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
43
 
46
- export { type SoonOptions, createShortAPI, createShortMethods, createSoon, mergeHeaders, mergeSignal, mergeUrl, parseUrlOptions, stringifyBody };
44
+ export { type SoonOptions, createShortAPI, createShortMethods, createSoon, mergeHeaders, mergeSignals, mergeUrl, parseUrlOptions, stringifyBody };
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.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};
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:i,baseURL:c}=o;let f=a.trim();t(a).forEach((t=>{i&&(f=f.replace(":"+t,""+i[t]))}));const[u,h]=f.split("?"),y=new URLSearchParams([...e(h),...e(s)]);let l=((t,e)=>{let a=r(t);return n(a)||(a=r(e)+a),a})(u,c);return y.size&&(l=l+"?"+y),l},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=(n??[]).filter((t=>!!t));return t&&r.push(AbortSignal.timeout(t)),r.length?AbortSignal.any(r):void 0};function i(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 c(t){const{url:n,options:r,baseURL:e,baseOptions:c}=t,f={...c,...r};f.signal=s(f.timeout,[f.signal]);const u=a(n,{...f,baseURL:e}),[h,y]=i(f.body);f.body=h;const l=o(c?.headers,r?.headers,y?{"Content-Type":"application/json"}:void 0);return f.headers=l,[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,i]=a,c="get"===t?"query":"body";return n(r,{...e,method:t,params:o?s:void 0,[c]:o?i:s})}})),a}}export{y as createShortAPI,h as createShortMethods,u as createSoon,o as mergeHeaders,s as mergeSignals,a as mergeUrl,c as parseUrlOptions,i as stringifyBody};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soon-fetch",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
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",