openapi-fetch
Advanced tools
Comparing version 0.11.1 to 0.11.2
# openapi-fetch | ||
## 0.11.2 | ||
### Patch Changes | ||
- [#1817](https://github.com/openapi-ts/openapi-typescript/pull/1817) [`2a4b067`](https://github.com/openapi-ts/openapi-typescript/commit/2a4b067f43f7e0b75aecbf5c2fb3013a4e96e591) Thanks [@Gruak](https://github.com/Gruak)! - Allow specifying baseUrl per request | ||
- [#1842](https://github.com/openapi-ts/openapi-typescript/pull/1842) [`0e42cbb`](https://github.com/openapi-ts/openapi-typescript/commit/0e42cbb98e2a023c33685de65ab0b8dbf82cc4b3) Thanks [@gzm0](https://github.com/gzm0)! - fix: allow use of `PathBasedClient` with generated `paths` | ||
## 0.11.1 | ||
@@ -4,0 +12,0 @@ |
@@ -113,2 +113,3 @@ import type { | ||
RequestBodyOption<T> & { | ||
baseUrl?: string; | ||
querySerializer?: QuerySerializer<T> | QuerySerializerOptions; | ||
@@ -155,3 +156,3 @@ bodySerializer?: BodySerializer<T>; | ||
/** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */ | ||
export type MaybeOptionalInit<Params extends Record<HttpMethod, {}>, Location extends keyof Params> = RequiredKeysOf< | ||
export type MaybeOptionalInit<Params, Location extends keyof Params> = RequiredKeysOf< | ||
FetchOptions<FilterKeys<Params, Location>> | ||
@@ -179,3 +180,3 @@ > extends never | ||
export type ClientForPath<PathInfo extends Record<HttpMethod, {}>, Media extends MediaType> = { | ||
export type ClientForPath<PathInfo, Media extends MediaType> = { | ||
[Method in keyof PathInfo as Uppercase<string & Method>]: <Init extends MaybeOptionalInit<PathInfo, Method>>( | ||
@@ -227,6 +228,3 @@ ...init: InitParam<Init> | ||
export type PathBasedClient< | ||
Paths extends Record<string, Record<HttpMethod, {}>>, | ||
Media extends MediaType = MediaType, | ||
> = { | ||
export type PathBasedClient<Paths, Media extends MediaType = MediaType> = { | ||
[Path in keyof Paths]: ClientForPath<Paths[Path], Media>; | ||
@@ -302,1 +300,4 @@ }; | ||
export declare function mergeHeaders(...allHeaders: (HeadersOptions | undefined)[]): Headers; | ||
/** Remove trailing slash from url */ | ||
export declare function removeTrailingSlash(url: string): string; |
@@ -43,5 +43,3 @@ // settings & const | ||
} = { ...clientOptions }; | ||
if (baseUrl.endsWith("/")) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1); | ||
} | ||
baseUrl = removeTrailingSlash(baseUrl); | ||
baseHeaders = mergeHeaders(DEFAULT_HEADERS, baseHeaders); | ||
@@ -57,2 +55,3 @@ const middlewares = []; | ||
const { | ||
baseUrl: localBaseUrl, | ||
fetch = baseFetch, | ||
@@ -66,2 +65,5 @@ headers, | ||
} = fetchOptions || {}; | ||
if (localBaseUrl) { | ||
baseUrl = removeTrailingSlash(localBaseUrl); | ||
} | ||
@@ -569,1 +571,12 @@ let querySerializer = | ||
} | ||
/** | ||
* Remove trailing slash from url | ||
* @type {import("./index.js").removeTrailingSlash} | ||
*/ | ||
export function removeTrailingSlash(url) { | ||
if (url.endsWith("/")) { | ||
return url.substring(0, url.length - 1); | ||
} | ||
return url; | ||
} |
@@ -113,2 +113,3 @@ import type { | ||
RequestBodyOption<T> & { | ||
baseUrl?: string; | ||
querySerializer?: QuerySerializer<T> | QuerySerializerOptions; | ||
@@ -155,3 +156,3 @@ bodySerializer?: BodySerializer<T>; | ||
/** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */ | ||
export type MaybeOptionalInit<Params extends Record<HttpMethod, {}>, Location extends keyof Params> = RequiredKeysOf< | ||
export type MaybeOptionalInit<Params, Location extends keyof Params> = RequiredKeysOf< | ||
FetchOptions<FilterKeys<Params, Location>> | ||
@@ -179,3 +180,3 @@ > extends never | ||
export type ClientForPath<PathInfo extends Record<HttpMethod, {}>, Media extends MediaType> = { | ||
export type ClientForPath<PathInfo, Media extends MediaType> = { | ||
[Method in keyof PathInfo as Uppercase<string & Method>]: <Init extends MaybeOptionalInit<PathInfo, Method>>( | ||
@@ -227,6 +228,3 @@ ...init: InitParam<Init> | ||
export type PathBasedClient< | ||
Paths extends Record<string, Record<HttpMethod, {}>>, | ||
Media extends MediaType = MediaType, | ||
> = { | ||
export type PathBasedClient<Paths, Media extends MediaType = MediaType> = { | ||
[Path in keyof Paths]: ClientForPath<Paths[Path], Media>; | ||
@@ -302,1 +300,4 @@ }; | ||
export declare function mergeHeaders(...allHeaders: (HeadersOptions | undefined)[]): Headers; | ||
/** Remove trailing slash from url */ | ||
export declare function removeTrailingSlash(url: string): string; |
@@ -1,1 +0,1 @@ | ||
var L={"Content-Type":"application/json"},N=/\{[^{}]+\}/g,g=class extends Request{constructor(e,t){super(e,t);for(let r in t)r in this||(this[r]=t[r])}};function k(){return Math.random().toString(36).slice(2,11)}function P(i){let{baseUrl:e="",fetch:t=globalThis.fetch,querySerializer:r,bodySerializer:n,headers:s,...l}={...i};e.endsWith("/")&&(e=e.substring(0,e.length-1)),s=D(L,s);let c=[];async function f(a,o){let{fetch:p=t,headers:H,params:b={},parseAs:T="json",querySerializer:m,bodySerializer:z=n??v,...I}=o||{},E=typeof r=="function"?r:C(r);m&&(E=typeof m=="function"?m:C({...typeof r=="object"?r:{},...m}));let y={redirect:"follow",...l,...I,headers:D(s,H,b.header)};y.body&&(y.body=z(y.body),y.body instanceof FormData&&y.headers.delete("Content-Type"));let j,x,w=new g(B(a,{baseUrl:e,params:b,querySerializer:E}),y);if(c.length){j=k(),x=Object.freeze({baseUrl:e,fetch:p,parseAs:T,querySerializer:E,bodySerializer:z});for(let d of c)if(d&&typeof d=="object"&&typeof d.onRequest=="function"){let h=await d.onRequest({request:w,schemaPath:a,params:b,options:x,id:j});if(h){if(!(h instanceof Request))throw new Error("onRequest: must return new Request() when modifying the request");w=h}}}let u=await p(w);if(c.length)for(let d=c.length-1;d>=0;d--){let h=c[d];if(h&&typeof h=="object"&&typeof h.onResponse=="function"){let S=await h.onResponse({request:w,response:u,schemaPath:a,params:b,options:x,id:j});if(S){if(!(S instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");u=S}}}if(u.status===204||u.headers.get("Content-Length")==="0")return u.ok?{data:{},response:u}:{error:{},response:u};if(u.ok)return T==="stream"?{data:u.body,response:u}:{data:await u[T](),response:u};let A=await u.text();try{A=JSON.parse(A)}catch{}return{error:A,response:u}}return{GET(a,o){return f(a,{...o,method:"GET"})},PUT(a,o){return f(a,{...o,method:"PUT"})},POST(a,o){return f(a,{...o,method:"POST"})},DELETE(a,o){return f(a,{...o,method:"DELETE"})},OPTIONS(a,o){return f(a,{...o,method:"OPTIONS"})},HEAD(a,o){return f(a,{...o,method:"HEAD"})},PATCH(a,o){return f(a,{...o,method:"PATCH"})},TRACE(a,o){return f(a,{...o,method:"TRACE"})},use(...a){for(let o of a)if(o){if(typeof o!="object"||!("onRequest"in o||"onResponse"in o))throw new Error("Middleware must be an object with one of `onRequest()` or `onResponse()`");c.push(o)}},eject(...a){for(let o of a){let p=c.indexOf(o);p!==-1&&c.splice(p,1)}}}}var $=class{constructor(e,t){this.client=e,this.url=t}GET(e){return this.client.GET(this.url,e)}PUT(e){return this.client.PUT(this.url,e)}POST(e){return this.client.POST(this.url,e)}DELETE(e){return this.client.DELETE(this.url,e)}OPTIONS(e){return this.client.OPTIONS(this.url,e)}HEAD(e){return this.client.HEAD(this.url,e)}PATCH(e){return this.client.PATCH(this.url,e)}TRACE(e){return this.client.TRACE(this.url,e)}},O=class{constructor(){this.client=null}get(e,t){let r=new $(e,t);return this.client[t]=r,r}};function F(i){let e=new O,t=new Proxy(i,e);function r(){}r.prototype=t;let n=new r;return e.client=n,n}function G(i){return F(P(i))}function R(i,e,t){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`${i}=${t?.allowReserved===!0?e:encodeURIComponent(e)}`}function U(i,e,t){if(!e||typeof e!="object")return"";let r=[],n={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(let c in e)r.push(c,t.allowReserved===!0?e[c]:encodeURIComponent(e[c]));let l=r.join(",");switch(t.style){case"form":return`${i}=${l}`;case"label":return`.${l}`;case"matrix":return`;${i}=${l}`;default:return l}}for(let l in e){let c=t.style==="deepObject"?`${i}[${l}]`:l;r.push(R(c,e[l],t))}let s=r.join(n);return t.style==="label"||t.style==="matrix"?`${n}${s}`:s}function q(i,e,t){if(!Array.isArray(e))return"";if(t.explode===!1){let s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",l=(t.allowReserved===!0?e:e.map(c=>encodeURIComponent(c))).join(s);switch(t.style){case"simple":return l;case"label":return`.${l}`;case"matrix":return`;${i}=${l}`;default:return`${i}=${l}`}}let r={simple:",",label:".",matrix:";"}[t.style]||"&",n=[];for(let s of e)t.style==="simple"||t.style==="label"?n.push(t.allowReserved===!0?s:encodeURIComponent(s)):n.push(R(i,s,t));return t.style==="label"||t.style==="matrix"?`${r}${n.join(r)}`:n.join(r)}function C(i){return function(t){let r=[];if(t&&typeof t=="object")for(let n in t){let s=t[n];if(s!=null){if(Array.isArray(s)){r.push(q(n,s,{style:"form",explode:!0,...i?.array,allowReserved:i?.allowReserved||!1}));continue}if(typeof s=="object"){r.push(U(n,s,{style:"deepObject",explode:!0,...i?.object,allowReserved:i?.allowReserved||!1}));continue}r.push(R(n,s,i))}}return r.join("&")}}function W(i,e){let t=i;for(let r of i.match(N)??[]){let n=r.substring(1,r.length-1),s=!1,l="simple";if(n.endsWith("*")&&(s=!0,n=n.substring(0,n.length-1)),n.startsWith(".")?(l="label",n=n.substring(1)):n.startsWith(";")&&(l="matrix",n=n.substring(1)),!e||e[n]===void 0||e[n]===null)continue;let c=e[n];if(Array.isArray(c)){t=t.replace(r,q(n,c,{style:l,explode:s}));continue}if(typeof c=="object"){t=t.replace(r,U(n,c,{style:l,explode:s}));continue}if(l==="matrix"){t=t.replace(r,`;${R(n,c)}`);continue}t=t.replace(r,l==="label"?`.${encodeURIComponent(c)}`:encodeURIComponent(c))}return t}function v(i){return i instanceof FormData?i:JSON.stringify(i)}function B(i,e){let t=`${e.baseUrl}${i}`;e.params?.path&&(t=W(t,e.params.path));let r=e.querySerializer(e.params.query??{});return r.startsWith("?")&&(r=r.substring(1)),r&&(t+=`?${r}`),t}function D(...i){let e=new Headers;for(let t of i){if(!t||typeof t!="object")continue;let r=t instanceof Headers?t.entries():Object.entries(t);for(let[n,s]of r)if(s===null)e.delete(n);else if(Array.isArray(s))for(let l of s)e.append(n,l);else s!==void 0&&e.set(n,s)}return e}export{B as createFinalURL,G as createPathBasedClient,C as createQuerySerializer,P as default,v as defaultBodySerializer,W as defaultPathSerializer,D as mergeHeaders,k as randomID,q as serializeArrayParam,U as serializeObjectParam,R as serializePrimitiveParam,F as wrapAsPathBasedClient}; | ||
var k={"Content-Type":"application/json"},v=/\{[^{}]+\}/g,g=class extends Request{constructor(e,t){super(e,t);for(let r in t)r in this||(this[r]=t[r])}};function B(){return Math.random().toString(36).slice(2,11)}function q(n){let{baseUrl:e="",fetch:t=globalThis.fetch,querySerializer:r,bodySerializer:i,headers:o,...l}={...n};e=P(e),o=D(k,o);let c=[];async function u(a,s){let{baseUrl:p,fetch:z=t,headers:L,params:b={},parseAs:T="json",querySerializer:m,bodySerializer:C=i??G,...N}=s||{};p&&(e=P(p));let E=typeof r=="function"?r:U(r);m&&(E=typeof m=="function"?m:U({...typeof r=="object"?r:{},...m}));let y={redirect:"follow",...l,...N,headers:D(o,L,b.header)};y.body&&(y.body=C(y.body),y.body instanceof FormData&&y.headers.delete("Content-Type"));let j,x,w=new g(M(a,{baseUrl:e,params:b,querySerializer:E}),y);if(c.length){j=B(),x=Object.freeze({baseUrl:e,fetch:z,parseAs:T,querySerializer:E,bodySerializer:C});for(let d of c)if(d&&typeof d=="object"&&typeof d.onRequest=="function"){let h=await d.onRequest({request:w,schemaPath:a,params:b,options:x,id:j});if(h){if(!(h instanceof Request))throw new Error("onRequest: must return new Request() when modifying the request");w=h}}}let f=await z(w);if(c.length)for(let d=c.length-1;d>=0;d--){let h=c[d];if(h&&typeof h=="object"&&typeof h.onResponse=="function"){let S=await h.onResponse({request:w,response:f,schemaPath:a,params:b,options:x,id:j});if(S){if(!(S instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");f=S}}}if(f.status===204||f.headers.get("Content-Length")==="0")return f.ok?{data:{},response:f}:{error:{},response:f};if(f.ok)return T==="stream"?{data:f.body,response:f}:{data:await f[T](),response:f};let A=await f.text();try{A=JSON.parse(A)}catch{}return{error:A,response:f}}return{GET(a,s){return u(a,{...s,method:"GET"})},PUT(a,s){return u(a,{...s,method:"PUT"})},POST(a,s){return u(a,{...s,method:"POST"})},DELETE(a,s){return u(a,{...s,method:"DELETE"})},OPTIONS(a,s){return u(a,{...s,method:"OPTIONS"})},HEAD(a,s){return u(a,{...s,method:"HEAD"})},PATCH(a,s){return u(a,{...s,method:"PATCH"})},TRACE(a,s){return u(a,{...s,method:"TRACE"})},use(...a){for(let s of a)if(s){if(typeof s!="object"||!("onRequest"in s||"onResponse"in s))throw new Error("Middleware must be an object with one of `onRequest()` or `onResponse()`");c.push(s)}},eject(...a){for(let s of a){let p=c.indexOf(s);p!==-1&&c.splice(p,1)}}}}var $=class{constructor(e,t){this.client=e,this.url=t}GET(e){return this.client.GET(this.url,e)}PUT(e){return this.client.PUT(this.url,e)}POST(e){return this.client.POST(this.url,e)}DELETE(e){return this.client.DELETE(this.url,e)}OPTIONS(e){return this.client.OPTIONS(this.url,e)}HEAD(e){return this.client.HEAD(this.url,e)}PATCH(e){return this.client.PATCH(this.url,e)}TRACE(e){return this.client.TRACE(this.url,e)}},O=class{constructor(){this.client=null}get(e,t){let r=new $(e,t);return this.client[t]=r,r}};function F(n){let e=new O,t=new Proxy(n,e);function r(){}r.prototype=t;let i=new r;return e.client=i,i}function Q(n){return F(q(n))}function R(n,e,t){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`${n}=${t?.allowReserved===!0?e:encodeURIComponent(e)}`}function H(n,e,t){if(!e||typeof e!="object")return"";let r=[],i={simple:",",label:".",matrix:";"}[t.style]||"&";if(t.style!=="deepObject"&&t.explode===!1){for(let c in e)r.push(c,t.allowReserved===!0?e[c]:encodeURIComponent(e[c]));let l=r.join(",");switch(t.style){case"form":return`${n}=${l}`;case"label":return`.${l}`;case"matrix":return`;${n}=${l}`;default:return l}}for(let l in e){let c=t.style==="deepObject"?`${n}[${l}]`:l;r.push(R(c,e[l],t))}let o=r.join(i);return t.style==="label"||t.style==="matrix"?`${i}${o}`:o}function I(n,e,t){if(!Array.isArray(e))return"";if(t.explode===!1){let o={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[t.style]||",",l=(t.allowReserved===!0?e:e.map(c=>encodeURIComponent(c))).join(o);switch(t.style){case"simple":return l;case"label":return`.${l}`;case"matrix":return`;${n}=${l}`;default:return`${n}=${l}`}}let r={simple:",",label:".",matrix:";"}[t.style]||"&",i=[];for(let o of e)t.style==="simple"||t.style==="label"?i.push(t.allowReserved===!0?o:encodeURIComponent(o)):i.push(R(n,o,t));return t.style==="label"||t.style==="matrix"?`${r}${i.join(r)}`:i.join(r)}function U(n){return function(t){let r=[];if(t&&typeof t=="object")for(let i in t){let o=t[i];if(o!=null){if(Array.isArray(o)){r.push(I(i,o,{style:"form",explode:!0,...n?.array,allowReserved:n?.allowReserved||!1}));continue}if(typeof o=="object"){r.push(H(i,o,{style:"deepObject",explode:!0,...n?.object,allowReserved:n?.allowReserved||!1}));continue}r.push(R(i,o,n))}}return r.join("&")}}function W(n,e){let t=n;for(let r of n.match(v)??[]){let i=r.substring(1,r.length-1),o=!1,l="simple";if(i.endsWith("*")&&(o=!0,i=i.substring(0,i.length-1)),i.startsWith(".")?(l="label",i=i.substring(1)):i.startsWith(";")&&(l="matrix",i=i.substring(1)),!e||e[i]===void 0||e[i]===null)continue;let c=e[i];if(Array.isArray(c)){t=t.replace(r,I(i,c,{style:l,explode:o}));continue}if(typeof c=="object"){t=t.replace(r,H(i,c,{style:l,explode:o}));continue}if(l==="matrix"){t=t.replace(r,`;${R(i,c)}`);continue}t=t.replace(r,l==="label"?`.${encodeURIComponent(c)}`:encodeURIComponent(c))}return t}function G(n){return n instanceof FormData?n:JSON.stringify(n)}function M(n,e){let t=`${e.baseUrl}${n}`;e.params?.path&&(t=W(t,e.params.path));let r=e.querySerializer(e.params.query??{});return r.startsWith("?")&&(r=r.substring(1)),r&&(t+=`?${r}`),t}function D(...n){let e=new Headers;for(let t of n){if(!t||typeof t!="object")continue;let r=t instanceof Headers?t.entries():Object.entries(t);for(let[i,o]of r)if(o===null)e.delete(i);else if(Array.isArray(o))for(let l of o)e.append(i,l);else o!==void 0&&e.set(i,o)}return e}function P(n){return n.endsWith("/")?n.substring(0,n.length-1):n}export{M as createFinalURL,Q as createPathBasedClient,U as createQuerySerializer,q as default,G as defaultBodySerializer,W as defaultPathSerializer,D as mergeHeaders,B as randomID,P as removeTrailingSlash,I as serializeArrayParam,H as serializeObjectParam,R as serializePrimitiveParam,F as wrapAsPathBasedClient}; |
{ | ||
"name": "openapi-fetch", | ||
"description": "Fast, type-safe fetch client for your OpenAPI schema. Only 5 kb (min). Works with React, Vue, Svelte, or vanilla JS.", | ||
"version": "0.11.1", | ||
"description": "Fast, type-safe fetch client for your OpenAPI schema. Only 6 kb (min). Works with React, Vue, Svelte, or vanilla JS.", | ||
"version": "0.11.2", | ||
"author": { | ||
@@ -53,13 +53,14 @@ "name": "Drew Powers", | ||
"devDependencies": { | ||
"axios": "^1.7.2", | ||
"axios": "^1.7.4", | ||
"del-cli": "^5.1.0", | ||
"esbuild": "^0.20.2", | ||
"esbuild": "^0.23.0", | ||
"execa": "^8.0.1", | ||
"feature-fetch": "^0.0.15", | ||
"msw": "^2.3.1", | ||
"openapi-typescript-codegen": "^0.25.0", | ||
"openapi-typescript-fetch": "^2.0.0", | ||
"superagent": "^9.0.2", | ||
"superagent": "^10.0.1", | ||
"typescript": "^5.4.5", | ||
"vite": "^5.3.5", | ||
"openapi-typescript": "^7.3.0" | ||
"openapi-typescript": "^7.3.1" | ||
}, | ||
@@ -81,2 +82,3 @@ "scripts": { | ||
"test-e2e": "playwright test", | ||
"bench:js": "vitest bench", | ||
"e2e-vite-build": "vite build test/fixtures/e2e", | ||
@@ -83,0 +85,0 @@ "e2e-vite-start": "vite preview test/fixtures/e2e", |
<img src="../../docs/public/assets/openapi-fetch.svg" alt="openapi-fetch" width="216" height="40" /> | ||
openapi-fetch is a type-safe fetch client that pulls in your OpenAPI schema. Weighs **5 kb** and has virtually zero runtime. Works with React, Vue, Svelte, or vanilla JS. | ||
openapi-fetch is a type-safe fetch client that pulls in your OpenAPI schema. Weighs **6 kb** and has virtually zero runtime. Works with React, Vue, Svelte, or vanilla JS. | ||
| Library | Size (min) | “GET” request\* | | ||
| :------------------------- | ---------: | :------------------------- | | ||
| openapi-fetch | `5 kB` | `300k` ops/s (fastest) | | ||
| openapi-typescript-fetch | `4 kB` | `150k` ops/s (2× slower) | | ||
| openapi-fetch | `6 kB` | `300k` ops/s (fastest) | | ||
| openapi-typescript-fetch | `3 kB` | `300k` ops/s (fastest) | | ||
| feature-fetch | `15 kB` | `300k` ops/s (fastest) | | ||
| axios | `32 kB` | `225k` ops/s (1.3× slower) | | ||
@@ -15,3 +16,3 @@ | superagent | `55 kB` | `50k` ops/s (6× slower) | | ||
The syntax is inspired by popular libraries like react-query or Apollo client, but without all the bells and whistles and in a 5 kb package. | ||
The syntax is inspired by popular libraries like react-query or Apollo client, but without all the bells and whistles and in a 6 kb package. | ||
@@ -51,3 +52,3 @@ ```ts | ||
- ✅ Also eliminates `as` type overrides that can also hide bugs | ||
- ✅ All of this in a **5 kb** client package 🎉 | ||
- ✅ All of this in a **6 kb** client package 🎉 | ||
@@ -64,3 +65,3 @@ ## Setup | ||
> **Highly recommended** | ||
> | ||
> | ||
> Enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson)) | ||
@@ -87,3 +88,3 @@ | ||
> **TIP:** | ||
> | ||
> | ||
> Use `tsc --noEmit` to check for type errors rather than relying on your linter or your build command. Nothing will typecheck as accurately as the TypeScript compiler itself. | ||
@@ -125,2 +126,2 @@ | ||
[View Docs](https://openapi-ts.dev/openapi-fetch/) | ||
[View Docs](https://openapi-ts.dev/openapi-fetch/) |
@@ -113,2 +113,3 @@ import type { | ||
RequestBodyOption<T> & { | ||
baseUrl?: string; | ||
querySerializer?: QuerySerializer<T> | QuerySerializerOptions; | ||
@@ -155,3 +156,3 @@ bodySerializer?: BodySerializer<T>; | ||
/** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */ | ||
export type MaybeOptionalInit<Params extends Record<HttpMethod, {}>, Location extends keyof Params> = RequiredKeysOf< | ||
export type MaybeOptionalInit<Params, Location extends keyof Params> = RequiredKeysOf< | ||
FetchOptions<FilterKeys<Params, Location>> | ||
@@ -179,3 +180,3 @@ > extends never | ||
export type ClientForPath<PathInfo extends Record<HttpMethod, {}>, Media extends MediaType> = { | ||
export type ClientForPath<PathInfo, Media extends MediaType> = { | ||
[Method in keyof PathInfo as Uppercase<string & Method>]: <Init extends MaybeOptionalInit<PathInfo, Method>>( | ||
@@ -227,6 +228,3 @@ ...init: InitParam<Init> | ||
export type PathBasedClient< | ||
Paths extends Record<string, Record<HttpMethod, {}>>, | ||
Media extends MediaType = MediaType, | ||
> = { | ||
export type PathBasedClient<Paths, Media extends MediaType = MediaType> = { | ||
[Path in keyof Paths]: ClientForPath<Paths[Path], Media>; | ||
@@ -302,1 +300,4 @@ }; | ||
export declare function mergeHeaders(...allHeaders: (HeadersOptions | undefined)[]): Headers; | ||
/** Remove trailing slash from url */ | ||
export declare function removeTrailingSlash(url: string): string; |
@@ -43,5 +43,3 @@ // settings & const | ||
} = { ...clientOptions }; | ||
if (baseUrl.endsWith("/")) { | ||
baseUrl = baseUrl.substring(0, baseUrl.length - 1); | ||
} | ||
baseUrl = removeTrailingSlash(baseUrl); | ||
baseHeaders = mergeHeaders(DEFAULT_HEADERS, baseHeaders); | ||
@@ -57,2 +55,3 @@ const middlewares = []; | ||
const { | ||
baseUrl: localBaseUrl, | ||
fetch = baseFetch, | ||
@@ -66,2 +65,5 @@ headers, | ||
} = fetchOptions || {}; | ||
if (localBaseUrl) { | ||
baseUrl = removeTrailingSlash(localBaseUrl); | ||
} | ||
@@ -569,1 +571,12 @@ let querySerializer = | ||
} | ||
/** | ||
* Remove trailing slash from url | ||
* @type {import("./index.js").removeTrailingSlash} | ||
*/ | ||
export function removeTrailingSlash(url) { | ||
if (url.endsWith("/")) { | ||
return url.substring(0, url.length - 1); | ||
} | ||
return url; | ||
} |
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
131796
2365
123
12