@hey-api/client-axios
Advanced tools
Comparing version 0.5.1 to 0.5.3
import { CreateAxiosDefaults, AxiosStatic, AxiosResponse, AxiosError, AxiosInstance } from 'axios'; | ||
type AuthToken = string | undefined; | ||
interface Auth { | ||
/** | ||
* Which part of the request do we use to send the auth? | ||
* | ||
* @default 'header' | ||
*/ | ||
in?: 'header' | 'query'; | ||
/** | ||
* Header or query parameter name. | ||
* | ||
* @default 'Authorization' | ||
*/ | ||
name?: string; | ||
@@ -36,5 +47,22 @@ scheme?: 'basic' | 'bearer'; | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
interface Config<ThrowOnError extends boolean = boolean> extends Omit<CreateAxiosDefaults, 'auth' | 'headers'> { | ||
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 Config$1 { | ||
/** | ||
* Auth token or a function returning auth token. The resolved value will be | ||
@@ -45,9 +73,2 @@ * added to the request payload as defined by its `security` array. | ||
/** | ||
* Axios implementation. You can use this option to provide a custom | ||
* Axios instance. | ||
* | ||
* @default axios | ||
*/ | ||
axios?: AxiosStatic; | ||
/** | ||
* A function for serializing request body parameter. By default, | ||
@@ -63,3 +84,3 @@ * {@link JSON.stringify()} will be used. | ||
*/ | ||
headers?: CreateAxiosDefaults['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>; | ||
headers?: RequestInit['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>; | ||
/** | ||
@@ -70,3 +91,3 @@ * The request method. | ||
*/ | ||
method?: 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace'; | ||
method?: 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'; | ||
/** | ||
@@ -94,3 +115,20 @@ * A function for serializing request query parameters. By default, arrays | ||
responseValidator?: (data: unknown) => Promise<unknown>; | ||
} | ||
interface Config<ThrowOnError extends boolean = boolean> extends Omit<CreateAxiosDefaults, 'auth' | 'headers' | 'method'>, Config$1 { | ||
/** | ||
* Axios implementation. You can use this option to provide a custom | ||
* Axios instance. | ||
* | ||
* @default axios | ||
*/ | ||
axios?: AxiosStatic; | ||
/** | ||
* 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?: CreateAxiosDefaults['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>; | ||
/** | ||
* Throw an error instead of returning it in the response? | ||
@@ -102,3 +140,2 @@ * | ||
} | ||
type AuthToken = string | undefined; | ||
interface RequestOptions<ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<ThrowOnError> { | ||
@@ -111,8 +148,2 @@ /** | ||
body?: unknown; | ||
/** | ||
* You can provide a client instance returned by `createClient()` instead of | ||
* individual options. This might be also useful if you want to implement a | ||
* custom client. | ||
*/ | ||
client?: Client; | ||
path?: Record<string, unknown>; | ||
@@ -134,25 +165,21 @@ query?: Record<string, unknown>; | ||
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 { | ||
/** | ||
* 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'> & Omit<Options<TData>, 'axios'>) => string; | ||
delete: MethodFn; | ||
get: MethodFn; | ||
getConfig: () => Config; | ||
head: MethodFn; | ||
type BuildUrlFn = <TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}>(options: Pick<TData, 'url'> & Omit<Options<TData>, 'axios'>) => string; | ||
type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn> & { | ||
instance: AxiosInstance; | ||
options: MethodFn; | ||
patch: MethodFn; | ||
post: MethodFn; | ||
put: MethodFn; | ||
request: RequestFn; | ||
setConfig: (config: Config) => Config; | ||
} | ||
interface DataShape { | ||
}; | ||
/** | ||
* 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 TDataShape { | ||
body?: unknown; | ||
@@ -164,3 +191,4 @@ headers?: unknown; | ||
} | ||
type Options<TData extends DataShape = DataShape, ThrowOnError extends boolean = boolean> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; | ||
type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean> = TData extends { | ||
@@ -174,6 +202,6 @@ body?: any; | ||
declare const createConfig: (override?: Config) => Config; | ||
declare const createClient: (config?: Config) => Client; | ||
declare const createClient: (config: Config) => Client; | ||
declare const createConfig: CreateClientConfig; | ||
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, type TDataShape, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer }; |
@@ -1,2 +0,2 @@ | ||
import D from'axios';var R=async(t,e)=>{let r=typeof e=="function"?await e(t):e;if(r)return t.scheme==="bearer"?`Bearer ${r}`:t.scheme==="basic"?`Basic ${btoa(r)}`:r},w=(t,e,r)=>{typeof r=="string"||r instanceof Blob?t.append(e,r):t.append(e,JSON.stringify(r));},C=(t,e,r)=>{typeof r=="string"?t.append(e,r):t.append(e,JSON.stringify(r));},O={bodySerializer:t=>{let e=new FormData;return Object.entries(t).forEach(([r,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>w(e,r,a)):w(e,r,i));}),e}},q={bodySerializer:t=>JSON.stringify(t)},v={bodySerializer:t=>{let e=new URLSearchParams;return Object.entries(t).forEach(([r,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>C(e,r,a)):C(e,r,i));}),e}},$=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},P=t=>{switch(t){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},k=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},h=({allowReserved:t,explode:e,name:r,style:i,value:a})=>{if(!e){let n=(t?a:a.map(o=>encodeURIComponent(o))).join(P(i));switch(i){case "label":return `.${n}`;case "matrix":return `;${r}=${n}`;case "simple":return n;default:return `${r}=${n}`}}let s=$(i),l=a.map(n=>i==="label"||i==="simple"?t?n:encodeURIComponent(n):d({allowReserved:t,name:r,value:n})).join(s);return i==="label"||i==="matrix"?s+l:l},d=({allowReserved:t,name:e,value:r})=>{if(r==null)return "";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return `${e}=${t?r:encodeURIComponent(r)}`},g=({allowReserved:t,explode:e,name:r,style:i,value:a})=>{if(a instanceof Date)return `${r}=${a.toISOString()}`;if(i!=="deepObject"&&!e){let n=[];Object.entries(a).forEach(([u,f])=>{n=[...n,u,t?f:encodeURIComponent(f)];});let o=n.join(",");switch(i){case "form":return `${r}=${o}`;case "label":return `.${o}`;case "matrix":return `;${r}=${o}`;default:return o}}let s=k(i),l=Object.entries(a).map(([n,o])=>d({allowReserved:t,name:i==="deepObject"?`${r}[${n}]`:n,value:o})).join(s);return i==="label"||i==="matrix"?s+l:l};var E=/\{[^{}]+\}/g,U=({path:t,url:e})=>{let r=e,i=e.match(E);if(i)for(let a of i){let s=false,l=a.substring(1,a.length-1),n="simple";l.endsWith("*")&&(s=true,l=l.substring(0,l.length-1)),l.startsWith(".")?(l=l.substring(1),n="label"):l.startsWith(";")&&(l=l.substring(1),n="matrix");let o=t[l];if(o==null)continue;if(Array.isArray(o)){r=r.replace(a,h({explode:s,name:l,style:n,value:o}));continue}if(typeof o=="object"){r=r.replace(a,g({explode:s,name:l,style:n,value:o}));continue}if(n==="matrix"){r=r.replace(a,`;${d({name:l,value:o})}`);continue}let u=encodeURIComponent(n==="label"?`.${o}`:o);r=r.replace(a,u);}return r},B=({allowReserved:t,array:e,object:r}={})=>a=>{let s=[];if(a&&typeof a=="object")for(let l in a){let n=a[l];if(n!=null){if(Array.isArray(n)){s=[...s,h({allowReserved:t,explode:true,name:l,style:"form",value:n,...e})];continue}if(typeof n=="object"){s=[...s,g({allowReserved:t,explode:true,name:l,style:"deepObject",value:n,...r})];continue}s=[...s,d({allowReserved:t,name:l,value:n})];}}return s.join("&")},A=async({security:t,...e})=>{for(let r of t){let i=await R(r,e.auth);if(!i)continue;let a=r.name??"Authorization";switch(r.in){case "query":e.query||(e.query={}),e.query[a]=i;break;case "header":default:e.headers[a]=i;break}return}},b=t=>H({path:t.path,query:t.paramsSerializer?undefined:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:B(t.querySerializer),url:t.url}),H=({path:t,query:e,querySerializer:r,url:i})=>{let s=i.startsWith("/")?i:`/${i}`;t&&(s=U({path:t,url:s}));let l=e?r(e):"";return l.startsWith("?")&&(l=l.substring(1)),l&&(s+=`?${l}`),s},x=(t,e)=>{let r={...t,...e};return r.headers=y(t.headers,e.headers),r},T=["common","delete","get","head","patch","post","put"],y=(...t)=>{let e={};for(let r of t){if(!r||typeof r!="object")continue;let i=Object.entries(r);for(let[a,s]of i)if(T.includes(a)&&typeof s=="object")e[a]={...e[a],...s};else if(s===null)delete e[a];else if(Array.isArray(s))for(let l of s)e[a]=[...e[a]??[],l];else s!==undefined&&(e[a]=typeof s=="object"?JSON.stringify(s):s);}return e},S=(t={})=>({baseURL:"",...t});var L=t=>{let e=x(S(),t),{auth:r,...i}=e,a=D.create(i),s=()=>({...e}),l=o=>(e=x(e,o),a.defaults={...a.defaults,...e,headers:y(a.defaults.headers,e.headers)},s()),n=async o=>{let u={...e,...o,axios:o.axios??e.axios??a,headers:y(e.headers,o.headers)};u.security&&await A({...u,security:u.security}),u.body&&u.bodySerializer&&(u.body=u.bodySerializer(u.body));let f=b(u);try{let m=u.axios,{auth:c,...j}=u,z=await m({...j,data:u.body,headers:u.headers,params:u.paramsSerializer?u.query:void 0,url:f}),{data:p}=z;return u.responseType==="json"&&(u.responseValidator&&await u.responseValidator(p),u.responseTransformer&&(p=await u.responseTransformer(p))),{...z,data:p??{}}}catch(m){let c=m;if(u.throwOnError)throw c;return c.error=c.response?.data??{},c}};return {buildUrl:b,delete:o=>n({...o,method:"delete"}),get:o=>n({...o,method:"get"}),getConfig:s,head:o=>n({...o,method:"head"}),instance:a,options:o=>n({...o,method:"options"}),patch:o=>n({...o,method:"patch"}),post:o=>n({...o,method:"post"}),put:o=>n({...o,method:"put"}),request:n,setConfig:l}};export{L as createClient,S as createConfig,O as formDataBodySerializer,q as jsonBodySerializer,v as urlSearchParamsBodySerializer};//# sourceMappingURL=index.js.map | ||
import B from'axios';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},z=(t,r,e)=>{typeof e=="string"||e instanceof Blob?t.append(r,e):t.append(r,JSON.stringify(e));},w=(t,r,e)=>{typeof e=="string"?t.append(r,e):t.append(r,JSON.stringify(e));},j={bodySerializer:t=>{let r=new FormData;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>z(r,e,a)):z(r,e,i));}),r}},q={bodySerializer:t=>JSON.stringify(t,(r,e)=>typeof e=="bigint"?e.toString():e)},P={bodySerializer:t=>{let r=new URLSearchParams;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>w(r,e,a)):w(r,e,i));}),r}},v=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 ","}},k=t=>{switch(t){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},h=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(!r){let n=(t?a:a.map(o=>encodeURIComponent(o))).join($(i));switch(i){case "label":return `.${n}`;case "matrix":return `;${e}=${n}`;case "simple":return n;default:return `${e}=${n}`}}let s=v(i),l=a.map(n=>i==="label"||i==="simple"?t?n:encodeURIComponent(n):f({allowReserved:t,name:e,value:n})).join(s);return i==="label"||i==="matrix"?s+l:l},f=({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)}`},g=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(i!=="deepObject"&&!r){let n=[];Object.entries(a).forEach(([u,d])=>{n=[...n,u,t?d:encodeURIComponent(d)];});let o=n.join(",");switch(i){case "form":return `${e}=${o}`;case "label":return `.${o}`;case "matrix":return `;${e}=${o}`;default:return o}}let s=k(i),l=Object.entries(a).map(([n,o])=>f({allowReserved:t,name:i==="deepObject"?`${e}[${n}]`:n,value:o})).join(s);return i==="label"||i==="matrix"?s+l:l};var E=/\{[^{}]+\}/g,T=({path:t,url:r})=>{let e=r,i=r.match(E);if(i)for(let a of i){let s=false,l=a.substring(1,a.length-1),n="simple";l.endsWith("*")&&(s=true,l=l.substring(0,l.length-1)),l.startsWith(".")?(l=l.substring(1),n="label"):l.startsWith(";")&&(l=l.substring(1),n="matrix");let o=t[l];if(o==null)continue;if(Array.isArray(o)){e=e.replace(a,h({explode:s,name:l,style:n,value:o}));continue}if(typeof o=="object"){e=e.replace(a,g({explode:s,name:l,style:n,value:o}));continue}if(n==="matrix"){e=e.replace(a,`;${f({name:l,value:o})}`);continue}let u=encodeURIComponent(n==="label"?`.${o}`:o);e=e.replace(a,u);}return e},U=({allowReserved:t,array:r,object:e}={})=>a=>{let s=[];if(a&&typeof a=="object")for(let l in a){let n=a[l];if(n!=null){if(Array.isArray(n)){s=[...s,h({allowReserved:t,explode:true,name:l,style:"form",value:n,...r})];continue}if(typeof n=="object"){s=[...s,g({allowReserved:t,explode:true,name:l,style:"deepObject",value:n,...e})];continue}s=[...s,f({allowReserved:t,name:l,value:n})];}}return s.join("&")},R=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[a]=i;break}return}},b=t=>D({path:t.path,query:t.paramsSerializer?undefined:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:U(t.querySerializer),url:t.url}),D=({path:t,query:r,querySerializer:e,url:i})=>{let s=i.startsWith("/")?i:`/${i}`;t&&(s=T({path:t,url:s}));let l=r?e(r):"";return l.startsWith("?")&&(l=l.substring(1)),l&&(s+=`?${l}`),s},S=(t,r)=>{let e={...t,...r};return e.headers=y(t.headers,r.headers),e},H=["common","delete","get","head","patch","post","put"],y=(...t)=>{let r={};for(let e of t){if(!e||typeof e!="object")continue;let i=Object.entries(e);for(let[a,s]of i)if(H.includes(a)&&typeof s=="object")r[a]={...r[a],...s};else if(s===null)delete r[a];else if(Array.isArray(s))for(let l of s)r[a]=[...r[a]??[],l];else s!==undefined&&(r[a]=typeof s=="object"?JSON.stringify(s):s);}return r},x=(t={})=>({baseURL:"",...t});var I=(t={})=>{let r=S(x(),t),{auth:e,...i}=r,a=B.create(i),s=()=>({...r}),l=o=>(r=S(r,o),a.defaults={...a.defaults,...r,headers:y(a.defaults.headers,r.headers)},s()),n=async o=>{let u={...r,...o,axios:o.axios??r.axios??a,headers:y(r.headers,o.headers)};u.security&&await R({...u,security:u.security}),u.body&&u.bodySerializer&&(u.body=u.bodySerializer(u.body));let d=b(u);try{let m=u.axios,{auth:c,...O}=u,C=await m({...O,data:u.body,headers:u.headers,params:u.paramsSerializer?u.query:void 0,url:d}),{data:p}=C;return u.responseType==="json"&&(u.responseValidator&&await u.responseValidator(p),u.responseTransformer&&(p=await u.responseTransformer(p))),{...C,data:p??{}}}catch(m){let c=m;if(u.throwOnError)throw c;return c.error=c.response?.data??{},c}};return {buildUrl:b,delete:o=>n({...o,method:"DELETE"}),get:o=>n({...o,method:"GET"}),getConfig:s,head:o=>n({...o,method:"HEAD"}),instance:a,options:o=>n({...o,method:"OPTIONS"}),patch:o=>n({...o,method:"PATCH"}),post:o=>n({...o,method:"POST"}),put:o=>n({...o,method:"PUT"}),request:n,setConfig:l}};export{I as createClient,x as createConfig,j as formDataBodySerializer,q as jsonBodySerializer,P as urlSearchParamsBodySerializer};//# sourceMappingURL=index.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@hey-api/client-axios", | ||
"version": "0.5.1", | ||
"version": "0.5.3", | ||
"description": "🚀 Axios client for `@hey-api/openapi-ts` codegen.", | ||
@@ -23,2 +23,3 @@ "homepage": "https://heyapi.dev/", | ||
"client", | ||
"codegen", | ||
"http", | ||
@@ -25,0 +26,0 @@ "javascript", |
114
src/index.ts
@@ -1,115 +0,6 @@ | ||
import type { AxiosError, RawAxiosRequestHeaders } from 'axios'; | ||
import axios from 'axios'; | ||
import type { Client, Config } from './types'; | ||
import { | ||
buildUrl, | ||
createConfig, | ||
mergeConfigs, | ||
mergeHeaders, | ||
setAuthParams, | ||
} from './utils'; | ||
export const createClient = (config: Config): Client => { | ||
let _config = mergeConfigs(createConfig(), config); | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const { auth, ...configWithoutAuth } = _config; | ||
const instance = axios.create(configWithoutAuth); | ||
const getConfig = (): Config => ({ ..._config }); | ||
const setConfig = (config: Config): Config => { | ||
_config = mergeConfigs(_config, config); | ||
instance.defaults = { | ||
...instance.defaults, | ||
..._config, | ||
// @ts-expect-error | ||
headers: mergeHeaders(instance.defaults.headers, _config.headers), | ||
}; | ||
return getConfig(); | ||
}; | ||
// @ts-expect-error | ||
const request: Client['request'] = async (options) => { | ||
const opts = { | ||
..._config, | ||
...options, | ||
axios: options.axios ?? _config.axios ?? instance, | ||
headers: mergeHeaders(_config.headers, options.headers), | ||
}; | ||
if (opts.security) { | ||
await setAuthParams({ | ||
...opts, | ||
security: opts.security, | ||
}); | ||
} | ||
if (opts.body && opts.bodySerializer) { | ||
opts.body = opts.bodySerializer(opts.body); | ||
} | ||
const url = buildUrl(opts); | ||
try { | ||
// assign Axios here for consistency with fetch | ||
const _axios = opts.axios; | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const { auth, ...optsWithoutAuth } = opts; | ||
const response = await _axios({ | ||
...optsWithoutAuth, | ||
data: opts.body, | ||
headers: opts.headers as RawAxiosRequestHeaders, | ||
// let `paramsSerializer()` handle query params if it exists | ||
params: opts.paramsSerializer ? opts.query : undefined, | ||
url, | ||
}); | ||
let { data } = response; | ||
if (opts.responseType === 'json') { | ||
if (opts.responseValidator) { | ||
await opts.responseValidator(data); | ||
} | ||
if (opts.responseTransformer) { | ||
data = await opts.responseTransformer(data); | ||
} | ||
} | ||
return { | ||
...response, | ||
data: data ?? {}, | ||
}; | ||
} catch (error) { | ||
const e = error as AxiosError; | ||
if (opts.throwOnError) { | ||
throw e; | ||
} | ||
// @ts-expect-error | ||
e.error = e.response?.data ?? {}; | ||
return e; | ||
} | ||
}; | ||
return { | ||
buildUrl, | ||
delete: (options) => request({ ...options, method: 'delete' }), | ||
get: (options) => request({ ...options, method: 'get' }), | ||
getConfig, | ||
head: (options) => request({ ...options, method: 'head' }), | ||
instance, | ||
options: (options) => request({ ...options, method: 'options' }), | ||
patch: (options) => request({ ...options, method: 'patch' }), | ||
post: (options) => request({ ...options, method: 'post' }), | ||
put: (options) => request({ ...options, method: 'put' }), | ||
request, | ||
setConfig, | ||
} as Client; | ||
}; | ||
export { createClient } from './client'; | ||
export type { | ||
Client, | ||
Config, | ||
CreateClientConfig, | ||
Options, | ||
@@ -119,2 +10,3 @@ OptionsLegacyParser, | ||
RequestResult, | ||
TDataShape, | ||
} from './types'; | ||
@@ -121,0 +13,0 @@ export { createConfig } from './utils'; |
119
src/types.ts
import type { | ||
Auth, | ||
BodySerializer, | ||
QuerySerializer, | ||
QuerySerializerOptions, | ||
Client as CoreClient, | ||
Config as CoreConfig, | ||
} from '@hey-api/client-core'; | ||
@@ -15,12 +14,6 @@ import type { | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
export interface Config<ThrowOnError extends boolean = boolean> | ||
extends Omit<CreateAxiosDefaults, 'auth' | 'headers'> { | ||
extends Omit<CreateAxiosDefaults, 'auth' | '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; | ||
/** | ||
* Axios implementation. You can use this option to provide a custom | ||
@@ -33,7 +26,2 @@ * Axios instance. | ||
/** | ||
* A function for serializing request body parameter. By default, | ||
* {@link JSON.stringify()} will be used. | ||
*/ | ||
bodySerializer?: BodySerializer | null; | ||
/** | ||
* An object containing any HTTP headers that you want to pre-populate your | ||
@@ -57,39 +45,2 @@ * `Headers` object with. | ||
/** | ||
* 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'; | ||
/** | ||
* 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. | ||
* | ||
* 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} | ||
*/ | ||
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? | ||
@@ -102,4 +53,2 @@ * | ||
type AuthToken = string | undefined; | ||
export interface RequestOptions< | ||
@@ -115,8 +64,2 @@ ThrowOnError extends boolean = boolean, | ||
body?: unknown; | ||
/** | ||
* You can provide a client instance returned by `createClient()` instead of | ||
* individual options. This might be also useful if you want to implement a | ||
* custom client. | ||
*/ | ||
client?: Client; | ||
path?: Record<string, unknown>; | ||
@@ -159,30 +102,28 @@ query?: Record<string, unknown>; | ||
export interface Client { | ||
/** | ||
* 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'> & Omit<Options<TData>, 'axios'>, | ||
) => string; | ||
delete: MethodFn; | ||
get: MethodFn; | ||
getConfig: () => Config; | ||
head: MethodFn; | ||
type BuildUrlFn = < | ||
TData extends { | ||
body?: unknown; | ||
path?: Record<string, unknown>; | ||
query?: Record<string, unknown>; | ||
url: string; | ||
}, | ||
>( | ||
options: Pick<TData, 'url'> & Omit<Options<TData>, 'axios'>, | ||
) => string; | ||
export type Client = CoreClient<RequestFn, Config, MethodFn, BuildUrlFn> & { | ||
instance: AxiosInstance; | ||
options: MethodFn; | ||
patch: MethodFn; | ||
post: MethodFn; | ||
put: MethodFn; | ||
request: RequestFn; | ||
setConfig: (config: Config) => Config; | ||
} | ||
}; | ||
interface DataShape { | ||
/** | ||
* 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; | ||
export interface TDataShape { | ||
body?: unknown; | ||
@@ -195,4 +136,6 @@ headers?: unknown; | ||
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; | ||
export type Options< | ||
TData extends DataShape = DataShape, | ||
TData extends TDataShape = TDataShape, | ||
ThrowOnError extends boolean = boolean, | ||
@@ -199,0 +142,0 @@ > = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & |
@@ -13,3 +13,8 @@ import type { | ||
import type { Client, Config, RequestOptions } from './types'; | ||
import type { | ||
Client, | ||
Config, | ||
CreateClientConfig, | ||
RequestOptions, | ||
} from './types'; | ||
@@ -284,5 +289,5 @@ interface PathSerializer { | ||
export const createConfig = (override: Config = {}): Config => ({ | ||
export const createConfig: CreateClientConfig = (override = {}) => ({ | ||
baseURL: '', | ||
...override, | ||
}); |
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
111283
15
937