@hey-api/client-fetch
Advanced tools
Comparing version 0.5.4 to 0.5.5
@@ -105,8 +105,13 @@ type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; | ||
/** | ||
* A function for transforming response data before it's returned to the | ||
* caller function. This is an ideal place to post-process server data, | ||
* e.g. convert date ISO strings into native Date objects. | ||
* 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? | ||
@@ -113,0 +118,0 @@ * |
@@ -1,5 +0,5 @@ | ||
var k=/\{[^{}]+\}/g,h=({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)}`},U=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 "&"}},z=({allowReserved:t,explode:r,name:e,style:s,value:a})=>{if(!r){let n=(t?a:a.map(c=>encodeURIComponent(c))).join($(s));switch(s){case"label":return `.${n}`;case"matrix":return `;${e}=${n}`;case"simple":return n;default:return `${e}=${n}`}}let o=U(s),i=a.map(n=>s==="label"||s==="simple"?t?n:encodeURIComponent(n):h({allowReserved:t,name:e,value:n})).join(o);return s==="label"||s==="matrix"?o+i:i},C=({allowReserved:t,explode:r,name:e,style:s,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(s!=="deepObject"&&!r){let n=[];Object.entries(a).forEach(([f,p])=>{n=[...n,f,t?p:encodeURIComponent(p)];});let c=n.join(",");switch(s){case"form":return `${e}=${c}`;case"label":return `.${c}`;case"matrix":return `;${e}=${c}`;default:return c}}let o=D(s),i=Object.entries(a).map(([n,c])=>h({allowReserved:t,name:s==="deepObject"?`${e}[${n}]`:n,value:c})).join(o);return s==="label"||s==="matrix"?o+i:i},_=({path:t,url:r})=>{let e=r,s=r.match(k);if(s)for(let a of s){let o=!1,i=a.substring(1,a.length-1),n="simple";i.endsWith("*")&&(o=!0,i=i.substring(0,i.length-1)),i.startsWith(".")?(i=i.substring(1),n="label"):i.startsWith(";")&&(i=i.substring(1),n="matrix");let c=t[i];if(c==null)continue;if(Array.isArray(c)){e=e.replace(a,z({explode:o,name:i,style:n,value:c}));continue}if(typeof c=="object"){e=e.replace(a,C({explode:o,name:i,style:n,value:c}));continue}if(n==="matrix"){e=e.replace(a,`;${h({name:i,value:c})}`);continue}let f=encodeURIComponent(n==="label"?`.${c}`:c);e=e.replace(a,f);}return e},A=({allowReserved:t,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let i in a){let n=a[i];if(n!=null){if(Array.isArray(n)){o=[...o,z({allowReserved:t,explode:!0,name:i,style:"form",value:n,...r})];continue}if(typeof n=="object"){o=[...o,C({allowReserved:t,explode:!0,name:i,style:"deepObject",value:n,...e})];continue}o=[...o,h({allowReserved:t,name:i,value:n})];}}return o.join("&")},w=t=>{if(!t)return;let r=t.split(";")[0].trim();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"},H=async(t,r)=>{if(t.fn==="accessToken"){let e=typeof r.accessToken=="function"?await r.accessToken():r.accessToken;return e?`Bearer ${e}`:void 0}if(t.fn==="apiKey")return typeof r.apiKey=="function"?await r.apiKey():r.apiKey},P=async({security:t,...r})=>{for(let e of t){let s=await H(e,r);if(s){e.in==="header"?r.headers.set(e.name,s):e.in==="query"&&(r.query||(r.query={}),r.query[e.name]=s);return}}},b=t=>W({baseUrl:t.baseUrl??"",path:t.path,query:t.query,querySerializer:typeof t.querySerializer=="function"?t.querySerializer:A(t.querySerializer),url:t.url}),W=({baseUrl:t,path:r,query:e,querySerializer:s,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,i=t+o;r&&(i=_({path:r,url:i}));let n=e?s(e):"";return n.startsWith("?")&&(n=n.substring(1)),n&&(i+=`?${n}`),i},R=(t,r)=>{let e={...t,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=O(t.headers,r.headers),e},O=(...t)=>{let r=new Headers;for(let e of t){if(!e||typeof e!="object")continue;let s=e instanceof Headers?e.entries():Object.entries(e);for(let[a,o]of s)if(o===null)r.delete(a);else if(Array.isArray(o))for(let i of o)r.append(a,i);else o!==void 0&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},y=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];}},T=()=>({error:new y,request:new y,response:new y}),x=(t,r,e)=>{typeof e=="string"||e instanceof Blob?t.append(r,e):t.append(r,JSON.stringify(e));},B={bodySerializer:t=>{let r=new FormData;return Object.entries(t).forEach(([e,s])=>{s!=null&&(Array.isArray(s)?s.forEach(a=>x(r,e,a)):x(r,e,s));}),r}},E={bodySerializer:t=>JSON.stringify(t)},j=(t,r,e)=>{typeof e=="string"?t.append(r,e):t.append(r,JSON.stringify(e));},N={bodySerializer:t=>{let r=new URLSearchParams;return Object.entries(t).forEach(([e,s])=>{s!=null&&(Array.isArray(s)?s.forEach(a=>j(r,e,a)):j(r,e,s));}),r}},Q=A({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),K={"Content-Type":"application/json"},q=(t={})=>({...E,baseUrl:"",headers:K,parseAs:"auto",querySerializer:Q,...t});var M=(t={})=>{let r=R(q(),t),e=()=>({...r}),s=i=>(r=R(r,i),e()),a=T(),o=async i=>{let n={...r,...i,fetch:i.fetch??r.fetch??globalThis.fetch,headers:O(r.headers,i.headers)};n.security&&await P({...n,security:n.security}),n.body&&n.bodySerializer&&(n.body=n.bodySerializer(n.body)),n.body||n.headers.delete("Content-Type");let c=b(n),f={redirect:"follow",...n},p=new Request(c,f);for(let u of a.request._fns)p=await u(p,n);let I=n.fetch,l=await I(p);for(let u of a.response._fns)l=await u(l,p,n);let m={request:p,response:l};if(l.ok){if(l.status===204||l.headers.get("Content-Length")==="0")return {data:{},...m};if(n.parseAs==="stream")return {data:l.body,...m};let u=(n.parseAs==="auto"?w(l.headers.get("Content-Type")):n.parseAs)??"json",S=await l[u]();return u==="json"&&n.responseTransformer&&(S=await n.responseTransformer(S)),{data:S,...m}}let g=await l.text();try{g=JSON.parse(g);}catch{}let d=g;for(let u of a.error._fns)d=await u(g,l,p,n);if(d=d||{},n.throwOnError)throw d;return {error:d,...m}};return {buildUrl:b,connect:i=>o({...i,method:"CONNECT"}),delete:i=>o({...i,method:"DELETE"}),get:i=>o({...i,method:"GET"}),getConfig:e,head:i=>o({...i,method:"HEAD"}),interceptors:a,options:i=>o({...i,method:"OPTIONS"}),patch:i=>o({...i,method:"PATCH"}),post:i=>o({...i,method:"POST"}),put:i=>o({...i,method:"PUT"}),request:o,setConfig:s,trace:i=>o({...i,method:"TRACE"})}}; | ||
var k=/\{[^{}]+\}/g,S=({allowReserved:n,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}=${n?e:encodeURIComponent(e)}`},U=n=>{switch(n){case"label":return ".";case"matrix":return ";";case"simple":return ",";default:return "&"}},$=n=>{switch(n){case"form":return ",";case"pipeDelimited":return "|";case"spaceDelimited":return "%20";default:return ","}},D=n=>{switch(n){case"label":return ".";case"matrix":return ";";case"simple":return ",";default:return "&"}},z=({allowReserved:n,explode:r,name:e,style:s,value:a})=>{if(!r){let t=(n?a:a.map(c=>encodeURIComponent(c))).join($(s));switch(s){case"label":return `.${t}`;case"matrix":return `;${e}=${t}`;case"simple":return t;default:return `${e}=${t}`}}let o=U(s),i=a.map(t=>s==="label"||s==="simple"?n?t:encodeURIComponent(t):S({allowReserved:n,name:e,value:t})).join(o);return s==="label"||s==="matrix"?o+i:i},C=({allowReserved:n,explode:r,name:e,style:s,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(s!=="deepObject"&&!r){let t=[];Object.entries(a).forEach(([u,p])=>{t=[...t,u,n?p:encodeURIComponent(p)];});let c=t.join(",");switch(s){case"form":return `${e}=${c}`;case"label":return `.${c}`;case"matrix":return `;${e}=${c}`;default:return c}}let o=D(s),i=Object.entries(a).map(([t,c])=>S({allowReserved:n,name:s==="deepObject"?`${e}[${t}]`:t,value:c})).join(o);return s==="label"||s==="matrix"?o+i:i},_=({path:n,url:r})=>{let e=r,s=r.match(k);if(s)for(let a of s){let o=!1,i=a.substring(1,a.length-1),t="simple";i.endsWith("*")&&(o=!0,i=i.substring(0,i.length-1)),i.startsWith(".")?(i=i.substring(1),t="label"):i.startsWith(";")&&(i=i.substring(1),t="matrix");let c=n[i];if(c==null)continue;if(Array.isArray(c)){e=e.replace(a,z({explode:o,name:i,style:t,value:c}));continue}if(typeof c=="object"){e=e.replace(a,C({explode:o,name:i,style:t,value:c}));continue}if(t==="matrix"){e=e.replace(a,`;${S({name:i,value:c})}`);continue}let u=encodeURIComponent(t==="label"?`.${c}`:c);e=e.replace(a,u);}return e},w=({allowReserved:n,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let i in a){let t=a[i];if(t!=null){if(Array.isArray(t)){o=[...o,z({allowReserved:n,explode:!0,name:i,style:"form",value:t,...r})];continue}if(typeof t=="object"){o=[...o,C({allowReserved:n,explode:!0,name:i,style:"deepObject",value:t,...e})];continue}o=[...o,S({allowReserved:n,name:i,value:t})];}}return o.join("&")},A=n=>{if(!n)return;let r=n.split(";")[0].trim();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"},H=async(n,r)=>{if(n.fn==="accessToken"){let e=typeof r.accessToken=="function"?await r.accessToken():r.accessToken;return e?`Bearer ${e}`:void 0}if(n.fn==="apiKey")return typeof r.apiKey=="function"?await r.apiKey():r.apiKey},P=async({security:n,...r})=>{for(let e of n){let s=await H(e,r);if(s){e.in==="header"?r.headers.set(e.name,s):e.in==="query"&&(r.query||(r.query={}),r.query[e.name]=s);return}}},b=n=>W({baseUrl:n.baseUrl??"",path:n.path,query:n.query,querySerializer:typeof n.querySerializer=="function"?n.querySerializer:w(n.querySerializer),url:n.url}),W=({baseUrl:n,path:r,query:e,querySerializer:s,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,i=n+o;r&&(i=_({path:r,url:i}));let t=e?s(e):"";return t.startsWith("?")&&(t=t.substring(1)),t&&(i+=`?${t}`),i},R=(n,r)=>{let e={...n,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=O(n.headers,r.headers),e},O=(...n)=>{let r=new Headers;for(let e of n){if(!e||typeof e!="object")continue;let s=e instanceof Headers?e.entries():Object.entries(e);for(let[a,o]of s)if(o===null)r.delete(a);else if(Array.isArray(o))for(let i of o)r.append(a,i);else o!==void 0&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},y=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];}},T=()=>({error:new y,request:new y,response:new y}),x=(n,r,e)=>{typeof e=="string"||e instanceof Blob?n.append(r,e):n.append(r,JSON.stringify(e));},B={bodySerializer:n=>{let r=new FormData;return Object.entries(n).forEach(([e,s])=>{s!=null&&(Array.isArray(s)?s.forEach(a=>x(r,e,a)):x(r,e,s));}),r}},E={bodySerializer:n=>JSON.stringify(n)},j=(n,r,e)=>{typeof e=="string"?n.append(r,e):n.append(r,JSON.stringify(e));},N={bodySerializer:n=>{let r=new URLSearchParams;return Object.entries(n).forEach(([e,s])=>{s!=null&&(Array.isArray(s)?s.forEach(a=>j(r,e,a)):j(r,e,s));}),r}},Q=w({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),V={"Content-Type":"application/json"},q=(n={})=>({...E,baseUrl:"",headers:V,parseAs:"auto",querySerializer:Q,...n});var L=(n={})=>{let r=R(q(),n),e=()=>({...r}),s=i=>(r=R(r,i),e()),a=T(),o=async i=>{let t={...r,...i,fetch:i.fetch??r.fetch??globalThis.fetch,headers:O(r.headers,i.headers)};t.security&&await P({...t,security:t.security}),t.body&&t.bodySerializer&&(t.body=t.bodySerializer(t.body)),t.body||t.headers.delete("Content-Type");let c=b(t),u={redirect:"follow",...t},p=new Request(c,u);for(let f of a.request._fns)p=await f(p,t);let I=t.fetch,l=await I(p);for(let f of a.response._fns)l=await f(l,p,t);let m={request:p,response:l};if(l.ok){if(l.status===204||l.headers.get("Content-Length")==="0")return {data:{},...m};if(t.parseAs==="stream")return {data:l.body,...m};let f=(t.parseAs==="auto"?A(l.headers.get("Content-Type")):t.parseAs)??"json",h=await l[f]();return f==="json"&&(t.responseValidator&&await t.responseValidator(h),t.responseTransformer&&(h=await t.responseTransformer(h))),{data:h,...m}}let g=await l.text();try{g=JSON.parse(g);}catch{}let d=g;for(let f of a.error._fns)d=await f(g,l,p,t);if(d=d||{},t.throwOnError)throw d;return {error:d,...m}};return {buildUrl:b,connect:i=>o({...i,method:"CONNECT"}),delete:i=>o({...i,method:"DELETE"}),get:i=>o({...i,method:"GET"}),getConfig:e,head:i=>o({...i,method:"HEAD"}),interceptors:a,options:i=>o({...i,method:"OPTIONS"}),patch:i=>o({...i,method:"PATCH"}),post:i=>o({...i,method:"POST"}),put:i=>o({...i,method:"PUT"}),request:o,setConfig:s,trace:i=>o({...i,method:"TRACE"})}}; | ||
export { M as createClient, q as createConfig, B as formDataBodySerializer, E as jsonBodySerializer, N as urlSearchParamsBodySerializer }; | ||
export { L as createClient, q as createConfig, B as formDataBodySerializer, E as jsonBodySerializer, N as urlSearchParamsBodySerializer }; | ||
//# sourceMappingURL=index.js.map | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@hey-api/client-fetch", | ||
"version": "0.5.4", | ||
"version": "0.5.5", | ||
"description": "🚀 Fetch API client for `@hey-api/openapi-ts` codegen.", | ||
@@ -15,3 +15,3 @@ "homepage": "https://heyapi.dev/", | ||
"author": { | ||
"email": "lmenus@lmen.us", | ||
"email": "lubos@heyapi.dev", | ||
"name": "Lubos Menus", | ||
@@ -18,0 +18,0 @@ "url": "https://lmen.us" |
@@ -13,2 +13,3 @@ <div align="center"> | ||
- type-safe response data and errors | ||
- response data validation and transformation | ||
- access to the original request and response | ||
@@ -25,4 +26,10 @@ - granular request and response customization options | ||
Love Hey API? Please consider becoming a [sponsor](https://github.com/sponsors/hey-api). | ||
Love Hey API? Become our [sponsor](https://github.com/sponsors/hey-api). | ||
<p> | ||
<a href="https://kutt.it/pkEZyc" target="_blank"> | ||
<img alt="Stainless logo" height="50" src="https://heyapi.dev/images/stainless-logo-wordmark-480w.png" /> | ||
</a> | ||
</p> | ||
## GitHub Integration (coming soon) | ||
@@ -32,8 +39,4 @@ | ||
## Migrating from OpenAPI Typescript Codegen? | ||
## Migration Guides | ||
Please read our [migration guide](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen). | ||
## Contributing | ||
Want to get involved? Please refer to the [contributing guide](https://heyapi.dev/contributing.html). | ||
[OpenAPI Typescript Codegen](https://heyapi.dev/openapi-ts/migrating.html#openapi-typescript-codegen). |
@@ -109,4 +109,10 @@ import type { Client, Config, RequestOptions } from './types'; | ||
let data = await response[parseAs](); | ||
if (parseAs === 'json' && opts.responseTransformer) { | ||
data = await opts.responseTransformer(data); | ||
if (parseAs === 'json') { | ||
if (opts.responseValidator) { | ||
await opts.responseValidator(data); | ||
} | ||
if (opts.responseTransformer) { | ||
data = await opts.responseTransformer(data); | ||
} | ||
} | ||
@@ -113,0 +119,0 @@ |
@@ -91,8 +91,13 @@ import type { | ||
/** | ||
* A function for transforming response data before it's returned to the | ||
* caller function. This is an ideal place to post-process server data, | ||
* e.g. convert date ISO strings into native Date objects. | ||
* 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? | ||
@@ -99,0 +104,0 @@ * |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
138200
1490
40