@hey-api/client-fetch
Advanced tools
Comparing version 0.7.1 to 0.7.2
@@ -0,1 +1,2 @@ | ||
type AuthToken = string | undefined; | ||
interface Auth { | ||
@@ -34,22 +35,21 @@ in?: 'header' | 'query'; | ||
type ErrInterceptor<Err, Res, Req, Options> = (error: Err, response: Res, request: Req, options: Options) => Err | Promise<Err>; | ||
type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>; | ||
type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>; | ||
declare class Interceptors<Interceptor> { | ||
_fns: Interceptor[]; | ||
constructor(); | ||
clear(): void; | ||
exists(fn: Interceptor): boolean; | ||
eject(fn: Interceptor): void; | ||
use(fn: Interceptor): void; | ||
interface Client$1<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never> { | ||
/** | ||
* Returns the final request URL. | ||
*/ | ||
buildUrl: BuildUrlFn; | ||
connect: MethodFn; | ||
delete: MethodFn; | ||
get: MethodFn; | ||
getConfig: () => Config; | ||
head: MethodFn; | ||
options: MethodFn; | ||
patch: MethodFn; | ||
post: MethodFn; | ||
put: MethodFn; | ||
request: RequestFn; | ||
setConfig: (config: Config) => Config; | ||
trace: MethodFn; | ||
} | ||
interface Middleware<Req, Res, Err, Options> { | ||
error: Pick<Interceptors<ErrInterceptor<Err, Res, Req, Options>>, 'eject' | 'use'>; | ||
request: Pick<Interceptors<ReqInterceptor<Req, Options>>, 'eject' | 'use'>; | ||
response: Pick<Interceptors<ResInterceptor<Res, Req, Options>>, 'eject' | 'use'>; | ||
} | ||
declare const createConfig: (override?: Config) => Config; | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
interface Config<ThrowOnError extends boolean = boolean> extends Omit<RequestInit, 'body' | 'headers' | 'method'> { | ||
interface Config$1 { | ||
/** | ||
@@ -61,8 +61,2 @@ * Auth token or a function returning auth token. The resolved value will be | ||
/** | ||
* Base URL for all requests made by this client. | ||
* | ||
* @default '' | ||
*/ | ||
baseUrl?: string; | ||
/** | ||
* A function for serializing request body parameter. By default, | ||
@@ -73,9 +67,2 @@ * {@link JSON.stringify()} will be used. | ||
/** | ||
* Fetch API implementation. You can use this option to provide a custom | ||
* fetch instance. | ||
* | ||
* @default globalThis.fetch | ||
*/ | ||
fetch?: (request: Request) => ReturnType<typeof fetch>; | ||
/** | ||
* An object containing any HTTP headers that you want to pre-populate your | ||
@@ -94,11 +81,2 @@ * `Headers` object with. | ||
/** | ||
* Return the response data parsed in a specified format. By default, `auto` | ||
* will infer the appropriate method from the `Content-Type` response header. | ||
* You can override this behavior with any of the {@link Body} methods. | ||
* Select `stream` if you don't want to parse response data at all. | ||
* | ||
* @default 'auto' | ||
*/ | ||
parseAs?: Exclude<keyof Body, 'body' | 'bodyUsed'> | 'auto' | 'stream'; | ||
/** | ||
* A function for serializing request query parameters. By default, arrays | ||
@@ -108,2 +86,5 @@ * will be exploded in form style, objects will be exploded in deepObject | ||
* | ||
* This method will have no effect if the native `paramsSerializer()` Axios | ||
* API function is used. | ||
* | ||
* {@link https://swagger.io/docs/specification/serialization/#query View examples} | ||
@@ -123,3 +104,46 @@ */ | ||
responseValidator?: (data: unknown) => Promise<unknown>; | ||
} | ||
type ErrInterceptor<Err, Res, Req, Options> = (error: Err, response: Res, request: Req, options: Options) => Err | Promise<Err>; | ||
type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>; | ||
type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>; | ||
declare class Interceptors<Interceptor> { | ||
_fns: Interceptor[]; | ||
constructor(); | ||
clear(): void; | ||
exists(fn: Interceptor): boolean; | ||
eject(fn: Interceptor): void; | ||
use(fn: Interceptor): void; | ||
} | ||
interface Middleware<Req, Res, Err, Options> { | ||
error: Pick<Interceptors<ErrInterceptor<Err, Res, Req, Options>>, 'eject' | 'use'>; | ||
request: Pick<Interceptors<ReqInterceptor<Req, Options>>, 'eject' | 'use'>; | ||
response: Pick<Interceptors<ResInterceptor<Res, Req, Options>>, 'eject' | 'use'>; | ||
} | ||
declare const createConfig: CreateClientConfig; | ||
interface Config<ThrowOnError extends boolean = boolean> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config$1 { | ||
/** | ||
* Base URL for all requests made by this client. | ||
* | ||
* @default '' | ||
*/ | ||
baseUrl?: string; | ||
/** | ||
* Fetch API implementation. You can use this option to provide a custom | ||
* fetch instance. | ||
* | ||
* @default globalThis.fetch | ||
*/ | ||
fetch?: (request: Request) => ReturnType<typeof fetch>; | ||
/** | ||
* Return the response data parsed in a specified format. By default, `auto` | ||
* will infer the appropriate method from the `Content-Type` response header. | ||
* You can override this behavior with any of the {@link Body} methods. | ||
* Select `stream` if you don't want to parse response data at all. | ||
* | ||
* @default 'auto' | ||
*/ | ||
parseAs?: Exclude<keyof Body, 'body' | 'bodyUsed'> | 'auto' | 'stream'; | ||
/** | ||
* Throw an error instead of returning it in the response? | ||
@@ -131,3 +155,2 @@ * | ||
} | ||
type AuthToken = string | undefined; | ||
interface RequestOptions<ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<ThrowOnError> { | ||
@@ -170,26 +193,20 @@ /** | ||
type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>(options: Omit<RequestOptions<ThrowOnError>, 'method'> & Pick<Required<RequestOptions<ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError>; | ||
interface Client<Req = Request, Res = Response, Err = unknown, Opts = RequestOptions> { | ||
/** | ||
* Returns the final request URL. This method works only with experimental parser. | ||
*/ | ||
buildUrl: <TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}>(options: Pick<TData, 'url'> & Options<TData>) => string; | ||
connect: MethodFn; | ||
delete: MethodFn; | ||
get: MethodFn; | ||
getConfig: () => Config; | ||
head: MethodFn; | ||
interceptors: Middleware<Req, Res, Err, Opts>; | ||
options: MethodFn; | ||
patch: MethodFn; | ||
post: MethodFn; | ||
put: MethodFn; | ||
request: RequestFn; | ||
setConfig: (config: Config) => Config; | ||
trace: MethodFn; | ||
} | ||
type BuildUrlFn = <TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}>(options: Pick<TData, 'url'> & Options<TData>) => string; | ||
type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn> & { | ||
interceptors: Middleware<Request, Response, unknown, RequestOptions>; | ||
}; | ||
/** | ||
* The `createClientConfig()` function will be called on client initialization | ||
* and the returned object will become the client's initial configuration. | ||
* | ||
* You may want to initialize your client this way instead of calling | ||
* `setConfig()`. This is useful for example if you're using Next.js | ||
* to ensure your client always has the correct values. | ||
*/ | ||
type CreateClientConfig = (override?: Config) => Config; | ||
interface DataShape { | ||
@@ -202,2 +219,3 @@ body?: unknown; | ||
} | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
type Options<TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; | ||
@@ -214,2 +232,2 @@ type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean> = TData extends { | ||
export { type Auth, type Client, type Config, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer }; | ||
export { type Auth, type Client, type Config, type CreateClientConfig, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer }; |
@@ -1,2 +0,2 @@ | ||
var A=async(t,r)=>{let e=typeof r=="function"?await r(t):r;if(e)return t.scheme==="bearer"?`Bearer ${e}`:t.scheme==="basic"?`Basic ${btoa(e)}`:e},j=(t,r,e)=>{typeof e=="string"||e instanceof Blob?t.append(r,e):t.append(r,JSON.stringify(e));},z=(t,r,e)=>{typeof e=="string"?t.append(r,e):t.append(r,JSON.stringify(e));},U={bodySerializer:t=>{let r=new FormData;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>j(r,e,a)):j(r,e,i));}),r}},b={bodySerializer:t=>JSON.stringify(t)},k={bodySerializer:t=>{let r=new URLSearchParams;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>z(r,e,a)):z(r,e,i));}),r}},T=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},_=t=>{switch(t){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},D=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},q=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(!r){let s=(t?a:a.map(l=>encodeURIComponent(l))).join(_(i));switch(i){case "label":return `.${s}`;case "matrix":return `;${e}=${s}`;case "simple":return s;default:return `${e}=${s}`}}let o=T(i),n=a.map(s=>i==="label"||i==="simple"?t?s:encodeURIComponent(s):y({allowReserved:t,name:e,value:s})).join(o);return i==="label"||i==="matrix"?o+n:n},y=({allowReserved:t,name:r,value:e})=>{if(e==null)return "";if(typeof e=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return `${r}=${t?e:encodeURIComponent(e)}`},O=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(i!=="deepObject"&&!r){let s=[];Object.entries(a).forEach(([f,u])=>{s=[...s,f,t?u:encodeURIComponent(u)];});let l=s.join(",");switch(i){case "form":return `${e}=${l}`;case "label":return `.${l}`;case "matrix":return `;${e}=${l}`;default:return l}}let o=D(i),n=Object.entries(a).map(([s,l])=>y({allowReserved:t,name:i==="deepObject"?`${e}[${s}]`:s,value:l})).join(o);return i==="label"||i==="matrix"?o+n:n};var H=/\{[^{}]+\}/g,B=({path:t,url:r})=>{let e=r,i=r.match(H);if(i)for(let a of i){let o=false,n=a.substring(1,a.length-1),s="simple";n.endsWith("*")&&(o=true,n=n.substring(0,n.length-1)),n.startsWith(".")?(n=n.substring(1),s="label"):n.startsWith(";")&&(n=n.substring(1),s="matrix");let l=t[n];if(l==null)continue;if(Array.isArray(l)){e=e.replace(a,q({explode:o,name:n,style:s,value:l}));continue}if(typeof l=="object"){e=e.replace(a,O({explode:o,name:n,style:s,value:l}));continue}if(s==="matrix"){e=e.replace(a,`;${y({name:n,value:l})}`);continue}let f=encodeURIComponent(s==="label"?`.${l}`:l);e=e.replace(a,f);}return e},E=({allowReserved:t,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let n in a){let s=a[n];if(s!=null){if(Array.isArray(s)){o=[...o,q({allowReserved:t,explode:true,name:n,style:"form",value:s,...r})];continue}if(typeof s=="object"){o=[...o,O({allowReserved:t,explode:true,name:n,style:"deepObject",value:s,...e})];continue}o=[...o,y({allowReserved:t,name:n,value:s})];}}return o.join("&")},P=t=>{if(!t)return "stream";let r=t.split(";")[0]?.trim();if(r){if(r.startsWith("application/json")||r.endsWith("+json"))return "json";if(r==="multipart/form-data")return "formData";if(["application/","audio/","image/","video/"].some(e=>r.startsWith(e)))return "blob";if(r.startsWith("text/"))return "text"}},I=async({security:t,...r})=>{for(let e of t){let i=await A(e,r.auth);if(!i)continue;let a=e.name??"Authorization";switch(e.in){case "query":r.query||(r.query={}),r.query[a]=i;break;case "header":default:r.headers.set(a,i);break}return}},S=t=>W({baseUrl:t.baseUrl??"",path:t.path,query:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:E(t.querySerializer),url:t.url}),W=({baseUrl:t,path:r,query:e,querySerializer:i,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,n=t+o;r&&(n=B({path:r,url:n}));let s=e?i(e):"";return s.startsWith("?")&&(s=s.substring(1)),s&&(n+=`?${s}`),n},x=(t,r)=>{let e={...t,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=w(t.headers,r.headers),e},w=(...t)=>{let r=new Headers;for(let e of t){if(!e||typeof e!="object")continue;let i=e instanceof Headers?e.entries():Object.entries(e);for(let[a,o]of i)if(o===null)r.delete(a);else if(Array.isArray(o))for(let n of o)r.append(a,n);else o!==undefined&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},h=class{_fns;constructor(){this._fns=[];}clear(){this._fns=[];}exists(r){return this._fns.indexOf(r)!==-1}eject(r){let e=this._fns.indexOf(r);e!==-1&&(this._fns=[...this._fns.slice(0,e),...this._fns.slice(e+1)]);}use(r){this._fns=[...this._fns,r];}},v=()=>({error:new h,request:new h,response:new h}),N=E({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),Q={"Content-Type":"application/json"},C=(t={})=>({...b,baseUrl:"",headers:Q,parseAs:"auto",querySerializer:N,...t});var F=(t={})=>{let r=x(C(),t),e=()=>({...r}),i=n=>(r=x(r,n),e()),a=v(),o=async n=>{let s={...r,...n,fetch:n.fetch??r.fetch??globalThis.fetch,headers:w(r.headers,n.headers)};s.security&&await I({...s,security:s.security}),s.body&&s.bodySerializer&&(s.body=s.bodySerializer(s.body)),s.body||s.headers.delete("Content-Type");let l=S(s),f={redirect:"follow",...s},u=new Request(l,f);for(let p of a.request._fns)u=await p(u,s);let $=s.fetch,c=await $(u);for(let p of a.response._fns)c=await p(c,u,s);let m={request:u,response:c};if(c.ok){if(c.status===204||c.headers.get("Content-Length")==="0")return {data:{},...m};let p=(s.parseAs==="auto"?P(c.headers.get("Content-Type")):s.parseAs)??"json";if(p==="stream")return {data:c.body,...m};let R=await c[p]();return p==="json"&&(s.responseValidator&&await s.responseValidator(R),s.responseTransformer&&(R=await s.responseTransformer(R))),{data:R,...m}}let g=await c.text();try{g=JSON.parse(g);}catch{}let d=g;for(let p of a.error._fns)d=await p(g,c,u,s);if(d=d||{},s.throwOnError)throw d;return {error:d,...m}};return {buildUrl:S,connect:n=>o({...n,method:"CONNECT"}),delete:n=>o({...n,method:"DELETE"}),get:n=>o({...n,method:"GET"}),getConfig:e,head:n=>o({...n,method:"HEAD"}),interceptors:a,options:n=>o({...n,method:"OPTIONS"}),patch:n=>o({...n,method:"PATCH"}),post:n=>o({...n,method:"POST"}),put:n=>o({...n,method:"PUT"}),request:o,setConfig:i,trace:n=>o({...n,method:"TRACE"})}};export{F as createClient,C as createConfig,U as formDataBodySerializer,b as jsonBodySerializer,k as urlSearchParamsBodySerializer};//# sourceMappingURL=index.js.map | ||
var A=async(t,r)=>{let e=typeof r=="function"?await r(t):r;if(e)return t.scheme==="bearer"?`Bearer ${e}`:t.scheme==="basic"?`Basic ${btoa(e)}`:e},j=(t,r,e)=>{typeof e=="string"||e instanceof Blob?t.append(r,e):t.append(r,JSON.stringify(e));},z=(t,r,e)=>{typeof e=="string"?t.append(r,e):t.append(r,JSON.stringify(e));},U={bodySerializer:t=>{let r=new FormData;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>j(r,e,a)):j(r,e,i));}),r}},b={bodySerializer:t=>JSON.stringify(t)},k={bodySerializer:t=>{let r=new URLSearchParams;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>z(r,e,a)):z(r,e,i));}),r}},T=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},_=t=>{switch(t){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},D=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},q=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(!r){let s=(t?a:a.map(l=>encodeURIComponent(l))).join(_(i));switch(i){case "label":return `.${s}`;case "matrix":return `;${e}=${s}`;case "simple":return s;default:return `${e}=${s}`}}let o=T(i),n=a.map(s=>i==="label"||i==="simple"?t?s:encodeURIComponent(s):y({allowReserved:t,name:e,value:s})).join(o);return i==="label"||i==="matrix"?o+n:n},y=({allowReserved:t,name:r,value:e})=>{if(e==null)return "";if(typeof e=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return `${r}=${t?e:encodeURIComponent(e)}`},O=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(i!=="deepObject"&&!r){let s=[];Object.entries(a).forEach(([f,u])=>{s=[...s,f,t?u:encodeURIComponent(u)];});let l=s.join(",");switch(i){case "form":return `${e}=${l}`;case "label":return `.${l}`;case "matrix":return `;${e}=${l}`;default:return l}}let o=D(i),n=Object.entries(a).map(([s,l])=>y({allowReserved:t,name:i==="deepObject"?`${e}[${s}]`:s,value:l})).join(o);return i==="label"||i==="matrix"?o+n:n};var H=/\{[^{}]+\}/g,B=({path:t,url:r})=>{let e=r,i=r.match(H);if(i)for(let a of i){let o=false,n=a.substring(1,a.length-1),s="simple";n.endsWith("*")&&(o=true,n=n.substring(0,n.length-1)),n.startsWith(".")?(n=n.substring(1),s="label"):n.startsWith(";")&&(n=n.substring(1),s="matrix");let l=t[n];if(l==null)continue;if(Array.isArray(l)){e=e.replace(a,q({explode:o,name:n,style:s,value:l}));continue}if(typeof l=="object"){e=e.replace(a,O({explode:o,name:n,style:s,value:l}));continue}if(s==="matrix"){e=e.replace(a,`;${y({name:n,value:l})}`);continue}let f=encodeURIComponent(s==="label"?`.${l}`:l);e=e.replace(a,f);}return e},E=({allowReserved:t,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let n in a){let s=a[n];if(s!=null){if(Array.isArray(s)){o=[...o,q({allowReserved:t,explode:true,name:n,style:"form",value:s,...r})];continue}if(typeof s=="object"){o=[...o,O({allowReserved:t,explode:true,name:n,style:"deepObject",value:s,...e})];continue}o=[...o,y({allowReserved:t,name:n,value:s})];}}return o.join("&")},P=t=>{if(!t)return "stream";let r=t.split(";")[0]?.trim();if(r){if(r.startsWith("application/json")||r.endsWith("+json"))return "json";if(r==="multipart/form-data")return "formData";if(["application/","audio/","image/","video/"].some(e=>r.startsWith(e)))return "blob";if(r.startsWith("text/"))return "text"}},I=async({security:t,...r})=>{for(let e of t){let i=await A(e,r.auth);if(!i)continue;let a=e.name??"Authorization";switch(e.in){case "query":r.query||(r.query={}),r.query[a]=i;break;case "header":default:r.headers.set(a,i);break}return}},S=t=>W({baseUrl:t.baseUrl??"",path:t.path,query:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:E(t.querySerializer),url:t.url}),W=({baseUrl:t,path:r,query:e,querySerializer:i,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,n=t+o;r&&(n=B({path:r,url:n}));let s=e?i(e):"";return s.startsWith("?")&&(s=s.substring(1)),s&&(n+=`?${s}`),n},C=(t,r)=>{let e={...t,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=x(t.headers,r.headers),e},x=(...t)=>{let r=new Headers;for(let e of t){if(!e||typeof e!="object")continue;let i=e instanceof Headers?e.entries():Object.entries(e);for(let[a,o]of i)if(o===null)r.delete(a);else if(Array.isArray(o))for(let n of o)r.append(a,n);else o!==undefined&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},h=class{_fns;constructor(){this._fns=[];}clear(){this._fns=[];}exists(r){return this._fns.indexOf(r)!==-1}eject(r){let e=this._fns.indexOf(r);e!==-1&&(this._fns=[...this._fns.slice(0,e),...this._fns.slice(e+1)]);}use(r){this._fns=[...this._fns,r];}},v=()=>({error:new h,request:new h,response:new h}),N=E({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),Q={"Content-Type":"application/json"},w=(t={})=>({...b,baseUrl:"",headers:Q,parseAs:"auto",querySerializer:N,...t});var F=(t={})=>{let r=C(w(),t),e=()=>({...r}),i=n=>(r=C(r,n),e()),a=v(),o=async n=>{let s={...r,...n,fetch:n.fetch??r.fetch??globalThis.fetch,headers:x(r.headers,n.headers)};s.security&&await I({...s,security:s.security}),s.body&&s.bodySerializer&&(s.body=s.bodySerializer(s.body)),s.body||s.headers.delete("Content-Type");let l=S(s),f={redirect:"follow",...s},u=new Request(l,f);for(let p of a.request._fns)u=await p(u,s);let $=s.fetch,c=await $(u);for(let p of a.response._fns)c=await p(c,u,s);let m={request:u,response:c};if(c.ok){if(c.status===204||c.headers.get("Content-Length")==="0")return {data:{},...m};let p=(s.parseAs==="auto"?P(c.headers.get("Content-Type")):s.parseAs)??"json";if(p==="stream")return {data:c.body,...m};let R=await c[p]();return p==="json"&&(s.responseValidator&&await s.responseValidator(R),s.responseTransformer&&(R=await s.responseTransformer(R))),{data:R,...m}}let g=await c.text();try{g=JSON.parse(g);}catch{}let d=g;for(let p of a.error._fns)d=await p(g,c,u,s);if(d=d||{},s.throwOnError)throw d;return {error:d,...m}};return {buildUrl:S,connect:n=>o({...n,method:"CONNECT"}),delete:n=>o({...n,method:"DELETE"}),get:n=>o({...n,method:"GET"}),getConfig:e,head:n=>o({...n,method:"HEAD"}),interceptors:a,options:n=>o({...n,method:"OPTIONS"}),patch:n=>o({...n,method:"PATCH"}),post:n=>o({...n,method:"POST"}),put:n=>o({...n,method:"PUT"}),request:o,setConfig:i,trace:n=>o({...n,method:"TRACE"})}};export{F as createClient,w as createConfig,U as formDataBodySerializer,b as jsonBodySerializer,k as urlSearchParamsBodySerializer};//# sourceMappingURL=index.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@hey-api/client-fetch", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"description": "🚀 Fetch API client for `@hey-api/openapi-ts` codegen.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://heyapi.dev/", |
@@ -172,2 +172,3 @@ import type { Client, Config, RequestOptions } from './types'; | ||
Config, | ||
CreateClientConfig, | ||
Options, | ||
@@ -174,0 +175,0 @@ OptionsLegacyParser, |
133
src/types.ts
import type { | ||
Auth, | ||
BodySerializer, | ||
QuerySerializer, | ||
QuerySerializerOptions, | ||
Client as CoreClient, | ||
Config as CoreConfig, | ||
} from '@hey-api/client-core'; | ||
@@ -10,12 +9,6 @@ | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
export interface Config<ThrowOnError extends boolean = boolean> | ||
extends Omit<RequestInit, 'body' | 'headers' | 'method'> { | ||
extends Omit<RequestInit, 'body' | 'headers' | 'method'>, | ||
CoreConfig { | ||
/** | ||
* Auth token or a function returning auth token. The resolved value will be | ||
* added to the request payload as defined by its `security` array. | ||
*/ | ||
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken; | ||
/** | ||
* Base URL for all requests made by this client. | ||
@@ -27,7 +20,2 @@ * | ||
/** | ||
* A function for serializing request body parameter. By default, | ||
* {@link JSON.stringify()} will be used. | ||
*/ | ||
bodySerializer?: BodySerializer | null; | ||
/** | ||
* Fetch API implementation. You can use this option to provide a custom | ||
@@ -40,35 +28,2 @@ * fetch instance. | ||
/** | ||
* An object containing any HTTP headers that you want to pre-populate your | ||
* `Headers` object with. | ||
* | ||
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} | ||
*/ | ||
headers?: | ||
| RequestInit['headers'] | ||
| Record< | ||
string, | ||
| string | ||
| number | ||
| boolean | ||
| (string | number | boolean)[] | ||
| null | ||
| undefined | ||
| unknown | ||
>; | ||
/** | ||
* The request method. | ||
* | ||
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} | ||
*/ | ||
method?: | ||
| 'CONNECT' | ||
| 'DELETE' | ||
| 'GET' | ||
| 'HEAD' | ||
| 'OPTIONS' | ||
| 'PATCH' | ||
| 'POST' | ||
| 'PUT' | ||
| 'TRACE'; | ||
/** | ||
* Return the response data parsed in a specified format. By default, `auto` | ||
@@ -83,21 +38,2 @@ * will infer the appropriate method from the `Content-Type` response header. | ||
/** | ||
* A function for serializing request query parameters. By default, arrays | ||
* will be exploded in form style, objects will be exploded in deepObject | ||
* style, and reserved characters are percent-encoded. | ||
* | ||
* {@link https://swagger.io/docs/specification/serialization/#query View examples} | ||
*/ | ||
querySerializer?: QuerySerializer | QuerySerializerOptions; | ||
/** | ||
* A function transforming response data before it's returned. This is useful | ||
* for post-processing data, e.g. converting ISO strings into Date objects. | ||
*/ | ||
responseTransformer?: (data: unknown) => Promise<unknown>; | ||
/** | ||
* A function validating response data. This is useful if you want to ensure | ||
* the response conforms to the desired shape, so it can be safely passed to | ||
* the transformers and returned to the user. | ||
*/ | ||
responseValidator?: (data: unknown) => Promise<unknown>; | ||
/** | ||
* Throw an error instead of returning it in the response? | ||
@@ -110,4 +46,2 @@ * | ||
type AuthToken = string | undefined; | ||
export interface RequestOptions< | ||
@@ -180,36 +114,27 @@ ThrowOnError extends boolean = boolean, | ||
export interface Client< | ||
Req = Request, | ||
Res = Response, | ||
Err = unknown, | ||
Opts = RequestOptions, | ||
> { | ||
/** | ||
* Returns the final request URL. This method works only with experimental parser. | ||
*/ | ||
buildUrl: < | ||
TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}, | ||
>( | ||
options: Pick<TData, 'url'> & Options<TData>, | ||
) => string; | ||
connect: MethodFn; | ||
delete: MethodFn; | ||
get: MethodFn; | ||
getConfig: () => Config; | ||
head: MethodFn; | ||
interceptors: Middleware<Req, Res, Err, Opts>; | ||
options: MethodFn; | ||
patch: MethodFn; | ||
post: MethodFn; | ||
put: MethodFn; | ||
request: RequestFn; | ||
setConfig: (config: Config) => Config; | ||
trace: MethodFn; | ||
} | ||
type BuildUrlFn = < | ||
TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}, | ||
>( | ||
options: Pick<TData, 'url'> & Options<TData>, | ||
) => string; | ||
export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn> & { | ||
interceptors: Middleware<Request, Response, unknown, RequestOptions>; | ||
}; | ||
/** | ||
* The `createClientConfig()` function will be called on client initialization | ||
* and the returned object will become the client's initial configuration. | ||
* | ||
* You may want to initialize your client this way instead of calling | ||
* `setConfig()`. This is useful for example if you're using Next.js | ||
* to ensure your client always has the correct values. | ||
*/ | ||
export type CreateClientConfig = (override?: Config) => Config; | ||
interface DataShape { | ||
@@ -223,2 +148,4 @@ body?: unknown; | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
export type Options< | ||
@@ -225,0 +152,0 @@ TData extends DataShape = DataShape, |
@@ -13,3 +13,8 @@ import type { | ||
import type { Client, Config, RequestOptions } from './types'; | ||
import type { | ||
Client, | ||
Config, | ||
CreateClientConfig, | ||
RequestOptions, | ||
} from './types'; | ||
@@ -396,3 +401,3 @@ interface PathSerializer { | ||
export const createConfig = (override: Config = {}): Config => ({ | ||
export const createConfig: CreateClientConfig = (override = {}) => ({ | ||
...jsonBodySerializer, | ||
@@ -399,0 +404,0 @@ baseUrl: '', |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
124646
132570
1158
2
8
1