openapi-fetch
Advanced tools
Comparing version 0.10.2 to 0.10.3
# openapi-fetch | ||
## 0.10.3 | ||
### Patch Changes | ||
- [#1717](https://github.com/openapi-ts/openapi-typescript/pull/1717) [`335530c`](https://github.com/openapi-ts/openapi-typescript/commit/335530c4f8f966d0154f19504585c462f5f5a409) Thanks [@kerwanp](https://github.com/kerwanp)! - Ignore configuration files in published package | ||
- [#1717](https://github.com/openapi-ts/openapi-typescript/pull/1717) [`335530c`](https://github.com/openapi-ts/openapi-typescript/commit/335530c4f8f966d0154f19504585c462f5f5a409) Thanks [@kerwanp](https://github.com/kerwanp)! - Create own client type for easier reusability | ||
- Updated dependencies [[`335530c`](https://github.com/openapi-ts/openapi-typescript/commit/335530c4f8f966d0154f19504585c462f5f5a409)]: | ||
- openapi-typescript-helpers@0.0.10 | ||
## 0.10.2 | ||
@@ -4,0 +15,0 @@ |
@@ -128,4 +128,2 @@ import type { | ||
export interface MiddlewareCallbackParams { | ||
/** Final URL for this request */ | ||
readonly url: string; | ||
/** Current Request object */ | ||
@@ -173,5 +171,3 @@ request: Request; | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): { | ||
export interface Client<Paths extends {}, Media extends MediaType = MediaType> { | ||
/** Call a GET endpoint */ | ||
@@ -197,4 +193,8 @@ GET: ClientMethod<Paths, "get", Media>; | ||
eject(...middleware: Middleware[]): void; | ||
}; | ||
} | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): Client<Paths, Media>; | ||
/** Serialize primitive params to string */ | ||
@@ -201,0 +201,0 @@ export declare function serializePrimitiveParam( |
@@ -87,7 +87,7 @@ // settings & const | ||
requestInit.body = bodySerializer(requestInit.body); | ||
// remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression | ||
if (requestInit.body instanceof FormData) { | ||
requestInit.headers.delete("Content-Type"); | ||
} | ||
} | ||
// remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression | ||
if (requestInit.body instanceof FormData) { | ||
requestInit.headers.delete("Content-Type"); | ||
} | ||
@@ -94,0 +94,0 @@ let id; |
@@ -128,4 +128,2 @@ import type { | ||
export interface MiddlewareCallbackParams { | ||
/** Final URL for this request */ | ||
readonly url: string; | ||
/** Current Request object */ | ||
@@ -173,5 +171,3 @@ request: Request; | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): { | ||
export interface Client<Paths extends {}, Media extends MediaType = MediaType> { | ||
/** Call a GET endpoint */ | ||
@@ -197,4 +193,8 @@ GET: ClientMethod<Paths, "get", Media>; | ||
eject(...middleware: Middleware[]): void; | ||
}; | ||
} | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): Client<Paths, Media>; | ||
/** Serialize primitive params to string */ | ||
@@ -201,0 +201,0 @@ export declare function serializePrimitiveParam( |
@@ -1,1 +0,1 @@ | ||
var H={"Content-Type":"application/json"},I=/\{[^{}]+\}/g,E=class extends Request{constructor(t,e){super(t,e);for(let r in e)r in this||(this[r]=e[r])}};function P(){return Math.random().toString(36).slice(2,11)}function L(s){let{baseUrl:t="",fetch:e=globalThis.fetch,querySerializer:r,bodySerializer:n,headers:o,...a}={...s};t.endsWith("/")&&(t=t.substring(0,t.length-1)),o=O(H,o);let l=[];async function u(c,i){let{fetch:h=e,headers:C,params:b={},parseAs:j="json",querySerializer:m,bodySerializer:T=n??F,...D}=i||{},x=typeof r=="function"?r:z(r);m&&(x=typeof m=="function"?m:z({...typeof r=="object"?r:{},...m}));let p={redirect:"follow",...a,...D,headers:O(o,C,b.header)};p.body&&(p.body=T(p.body)),p.body instanceof FormData&&p.headers.delete("Content-Type");let g,$,R=new E(N(c,{baseUrl:t,params:b,querySerializer:x}),p);if(l.length){g=P(),$=Object.freeze({baseUrl:t,fetch:h,parseAs:j,querySerializer:x,bodySerializer:T});for(let d of l)if(d&&typeof d=="object"&&typeof d.onRequest=="function"){let y=await d.onRequest({request:R,schemaPath:c,params:b,options:$,id:g});if(y){if(!(y instanceof Request))throw new Error("onRequest: must return new Request() when modifying the request");R=y}}}let f=await h(R);if(l.length)for(let d=l.length-1;d>=0;d--){let y=l[d];if(y&&typeof y=="object"&&typeof y.onResponse=="function"){let A=await y.onResponse({request:R,response:f,schemaPath:c,params:b,options:$,id:g});if(A){if(!(A instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");f=A}}}if(f.status===204||f.headers.get("Content-Length")==="0")return f.ok?{data:{},response:f}:{error:{},response:f};if(f.ok)return j==="stream"?{data:f.body,response:f}:{data:await f[j](),response:f};let S=await f.text();try{S=JSON.parse(S)}catch{}return{error:S,response:f}}return{async GET(c,i){return u(c,{...i,method:"GET"})},async PUT(c,i){return u(c,{...i,method:"PUT"})},async POST(c,i){return u(c,{...i,method:"POST"})},async DELETE(c,i){return u(c,{...i,method:"DELETE"})},async OPTIONS(c,i){return u(c,{...i,method:"OPTIONS"})},async HEAD(c,i){return u(c,{...i,method:"HEAD"})},async PATCH(c,i){return u(c,{...i,method:"PATCH"})},async TRACE(c,i){return u(c,{...i,method:"TRACE"})},use(...c){for(let i of c)if(i){if(typeof i!="object"||!("onRequest"in i||"onResponse"in i))throw new Error("Middleware must be an object with one of `onRequest()` or `onResponse()`");l.push(i)}},eject(...c){for(let i of c){let h=l.indexOf(i);h!==-1&&l.splice(h,1)}}}}function w(s,t,e){if(t==null)return"";if(typeof t=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return`${s}=${e?.allowReserved===!0?t:encodeURIComponent(t)}`}function q(s,t,e){if(!t||typeof t!="object")return"";let r=[],n={simple:",",label:".",matrix:";"}[e.style]||"&";if(e.style!=="deepObject"&&e.explode===!1){for(let l in t)r.push(l,e.allowReserved===!0?t[l]:encodeURIComponent(t[l]));let a=r.join(",");switch(e.style){case"form":return`${s}=${a}`;case"label":return`.${a}`;case"matrix":return`;${s}=${a}`;default:return a}}for(let a in t){let l=e.style==="deepObject"?`${s}[${a}]`:a;r.push(w(l,t[a],e))}let o=r.join(n);return e.style==="label"||e.style==="matrix"?`${n}${o}`:o}function U(s,t,e){if(!Array.isArray(t))return"";if(e.explode===!1){let o={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[e.style]||",",a=(e.allowReserved===!0?t:t.map(l=>encodeURIComponent(l))).join(o);switch(e.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${s}=${a}`;default:return`${s}=${a}`}}let r={simple:",",label:".",matrix:";"}[e.style]||"&",n=[];for(let o of t)e.style==="simple"||e.style==="label"?n.push(e.allowReserved===!0?o:encodeURIComponent(o)):n.push(w(s,o,e));return e.style==="label"||e.style==="matrix"?`${r}${n.join(r)}`:n.join(r)}function z(s){return function(e){let r=[];if(e&&typeof e=="object")for(let n in e){let o=e[n];if(o!=null){if(Array.isArray(o)){r.push(U(n,o,{style:"form",explode:!0,...s?.array,allowReserved:s?.allowReserved||!1}));continue}if(typeof o=="object"){r.push(q(n,o,{style:"deepObject",explode:!0,...s?.object,allowReserved:s?.allowReserved||!1}));continue}r.push(w(n,o,s))}}return r.join("&")}}function k(s,t){let e=s;for(let r of s.match(I)??[]){let n=r.substring(1,r.length-1),o=!1,a="simple";if(n.endsWith("*")&&(o=!0,n=n.substring(0,n.length-1)),n.startsWith(".")?(a="label",n=n.substring(1)):n.startsWith(";")&&(a="matrix",n=n.substring(1)),!t||t[n]===void 0||t[n]===null)continue;let l=t[n];if(Array.isArray(l)){e=e.replace(r,U(n,l,{style:a,explode:o}));continue}if(typeof l=="object"){e=e.replace(r,q(n,l,{style:a,explode:o}));continue}if(a==="matrix"){e=e.replace(r,`;${w(n,l)}`);continue}e=e.replace(r,a==="label"?`.${encodeURIComponent(l)}`:encodeURIComponent(l))}return e}function F(s){return JSON.stringify(s)}function N(s,t){let e=`${t.baseUrl}${s}`;t.params?.path&&(e=k(e,t.params.path));let r=t.querySerializer(t.params.query??{});return r.startsWith("?")&&(r=r.substring(1)),r&&(e+=`?${r}`),e}function O(...s){let t=new Headers;for(let e of s){if(!e||typeof e!="object")continue;let r=e instanceof Headers?e.entries():Object.entries(e);for(let[n,o]of r)if(o===null)t.delete(n);else if(Array.isArray(o))for(let a of o)t.append(n,a);else o!==void 0&&t.set(n,o)}return t}export{N as createFinalURL,z as createQuerySerializer,L as default,F as defaultBodySerializer,k as defaultPathSerializer,O as mergeHeaders,P as randomID,U as serializeArrayParam,q as serializeObjectParam,w as serializePrimitiveParam}; | ||
var H={"Content-Type":"application/json"},I=/\{[^{}]+\}/g,E=class extends Request{constructor(t,e){super(t,e);for(let r in e)r in this||(this[r]=e[r])}};function P(){return Math.random().toString(36).slice(2,11)}function L(s){let{baseUrl:t="",fetch:e=globalThis.fetch,querySerializer:r,bodySerializer:n,headers:o,...a}={...s};t.endsWith("/")&&(t=t.substring(0,t.length-1)),o=O(H,o);let l=[];async function u(c,i){let{fetch:h=e,headers:C,params:b={},parseAs:j="json",querySerializer:m,bodySerializer:T=n??F,...D}=i||{},x=typeof r=="function"?r:z(r);m&&(x=typeof m=="function"?m:z({...typeof r=="object"?r:{},...m}));let p={redirect:"follow",...a,...D,headers:O(o,C,b.header)};p.body&&(p.body=T(p.body),p.body instanceof FormData&&p.headers.delete("Content-Type"));let g,$,R=new E(N(c,{baseUrl:t,params:b,querySerializer:x}),p);if(l.length){g=P(),$=Object.freeze({baseUrl:t,fetch:h,parseAs:j,querySerializer:x,bodySerializer:T});for(let d of l)if(d&&typeof d=="object"&&typeof d.onRequest=="function"){let y=await d.onRequest({request:R,schemaPath:c,params:b,options:$,id:g});if(y){if(!(y instanceof Request))throw new Error("onRequest: must return new Request() when modifying the request");R=y}}}let f=await h(R);if(l.length)for(let d=l.length-1;d>=0;d--){let y=l[d];if(y&&typeof y=="object"&&typeof y.onResponse=="function"){let A=await y.onResponse({request:R,response:f,schemaPath:c,params:b,options:$,id:g});if(A){if(!(A instanceof Response))throw new Error("onResponse: must return new Response() when modifying the response");f=A}}}if(f.status===204||f.headers.get("Content-Length")==="0")return f.ok?{data:{},response:f}:{error:{},response:f};if(f.ok)return j==="stream"?{data:f.body,response:f}:{data:await f[j](),response:f};let S=await f.text();try{S=JSON.parse(S)}catch{}return{error:S,response:f}}return{async GET(c,i){return u(c,{...i,method:"GET"})},async PUT(c,i){return u(c,{...i,method:"PUT"})},async POST(c,i){return u(c,{...i,method:"POST"})},async DELETE(c,i){return u(c,{...i,method:"DELETE"})},async OPTIONS(c,i){return u(c,{...i,method:"OPTIONS"})},async HEAD(c,i){return u(c,{...i,method:"HEAD"})},async PATCH(c,i){return u(c,{...i,method:"PATCH"})},async TRACE(c,i){return u(c,{...i,method:"TRACE"})},use(...c){for(let i of c)if(i){if(typeof i!="object"||!("onRequest"in i||"onResponse"in i))throw new Error("Middleware must be an object with one of `onRequest()` or `onResponse()`");l.push(i)}},eject(...c){for(let i of c){let h=l.indexOf(i);h!==-1&&l.splice(h,1)}}}}function w(s,t,e){if(t==null)return"";if(typeof t=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return`${s}=${e?.allowReserved===!0?t:encodeURIComponent(t)}`}function q(s,t,e){if(!t||typeof t!="object")return"";let r=[],n={simple:",",label:".",matrix:";"}[e.style]||"&";if(e.style!=="deepObject"&&e.explode===!1){for(let l in t)r.push(l,e.allowReserved===!0?t[l]:encodeURIComponent(t[l]));let a=r.join(",");switch(e.style){case"form":return`${s}=${a}`;case"label":return`.${a}`;case"matrix":return`;${s}=${a}`;default:return a}}for(let a in t){let l=e.style==="deepObject"?`${s}[${a}]`:a;r.push(w(l,t[a],e))}let o=r.join(n);return e.style==="label"||e.style==="matrix"?`${n}${o}`:o}function U(s,t,e){if(!Array.isArray(t))return"";if(e.explode===!1){let o={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[e.style]||",",a=(e.allowReserved===!0?t:t.map(l=>encodeURIComponent(l))).join(o);switch(e.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${s}=${a}`;default:return`${s}=${a}`}}let r={simple:",",label:".",matrix:";"}[e.style]||"&",n=[];for(let o of t)e.style==="simple"||e.style==="label"?n.push(e.allowReserved===!0?o:encodeURIComponent(o)):n.push(w(s,o,e));return e.style==="label"||e.style==="matrix"?`${r}${n.join(r)}`:n.join(r)}function z(s){return function(e){let r=[];if(e&&typeof e=="object")for(let n in e){let o=e[n];if(o!=null){if(Array.isArray(o)){r.push(U(n,o,{style:"form",explode:!0,...s?.array,allowReserved:s?.allowReserved||!1}));continue}if(typeof o=="object"){r.push(q(n,o,{style:"deepObject",explode:!0,...s?.object,allowReserved:s?.allowReserved||!1}));continue}r.push(w(n,o,s))}}return r.join("&")}}function k(s,t){let e=s;for(let r of s.match(I)??[]){let n=r.substring(1,r.length-1),o=!1,a="simple";if(n.endsWith("*")&&(o=!0,n=n.substring(0,n.length-1)),n.startsWith(".")?(a="label",n=n.substring(1)):n.startsWith(";")&&(a="matrix",n=n.substring(1)),!t||t[n]===void 0||t[n]===null)continue;let l=t[n];if(Array.isArray(l)){e=e.replace(r,U(n,l,{style:a,explode:o}));continue}if(typeof l=="object"){e=e.replace(r,q(n,l,{style:a,explode:o}));continue}if(a==="matrix"){e=e.replace(r,`;${w(n,l)}`);continue}e=e.replace(r,a==="label"?`.${encodeURIComponent(l)}`:encodeURIComponent(l))}return e}function F(s){return JSON.stringify(s)}function N(s,t){let e=`${t.baseUrl}${s}`;t.params?.path&&(e=k(e,t.params.path));let r=t.querySerializer(t.params.query??{});return r.startsWith("?")&&(r=r.substring(1)),r&&(e+=`?${r}`),e}function O(...s){let t=new Headers;for(let e of s){if(!e||typeof e!="object")continue;let r=e instanceof Headers?e.entries():Object.entries(e);for(let[n,o]of r)if(o===null)t.delete(n);else if(Array.isArray(o))for(let a of o)t.append(n,a);else o!==void 0&&t.set(n,o)}return t}export{N as createFinalURL,z as createQuerySerializer,L as default,F as defaultBodySerializer,k as defaultPathSerializer,O as mergeHeaders,P as randomID,U as serializeArrayParam,q as serializeObjectParam,w as serializePrimitiveParam}; |
{ | ||
"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.10.2", | ||
"version": "0.10.3", | ||
"author": { | ||
@@ -50,3 +50,3 @@ "name": "Drew Powers", | ||
"dependencies": { | ||
"openapi-typescript-helpers": "^0.0.9" | ||
"openapi-typescript-helpers": "^0.0.10" | ||
}, | ||
@@ -64,3 +64,3 @@ "devDependencies": { | ||
"vite": "^5.3.1", | ||
"openapi-typescript": "^7.0.0" | ||
"openapi-typescript": "^7.1.2" | ||
}, | ||
@@ -67,0 +67,0 @@ "scripts": { |
<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 **4 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 **5 kb** and has virtually zero runtime. Works with React, Vue, Svelte, or vanilla JS. | ||
@@ -15,3 +15,3 @@ | Library | Size (min) | “GET” request\* | | ||
The syntax is inspired by popular libraries like react-query or Apollo client, but without all the bells and whistles and in a 2 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 5 kb package. | ||
@@ -42,3 +42,3 @@ ```ts | ||
`GET`, `PUT`, `POST`, etc. are only thin wrappers around the native [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (which you can [swap for any call](https://openapi-ts.dev/openapi-fetch/api/#create-client)). | ||
`GET()`, `PUT()`, `POST()`, etc. are thin wrappers around the native [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) (which you can [swap for any call](https://openapi-ts.dev/openapi-fetch/api/#create-client)). | ||
@@ -54,3 +54,3 @@ Notice there are no generics, and no manual typing. Your endpoint’s request and response were inferred automatically. This is a huge improvement in the type safety of your endpoints because **every manual assertion could lead to a bug**! This eliminates all of the following: | ||
## 🔧 Setup | ||
## Setup | ||
@@ -64,3 +64,5 @@ Install this library along with [openapi-typescript](../openapi-typescript): | ||
> **Highly recommended**: enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson)) | ||
> **Highly recommended** | ||
> | ||
> Enable [noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess) in your `tsconfig.json` ([docs](/advanced#enable-nouncheckedindexaccess-in-your-tsconfigjson)) | ||
@@ -73,6 +75,4 @@ Next, generate TypeScript types from your OpenAPI schema using openapi-typescript: | ||
> ⚠️ Be sure to <a href="https://redocly.com/docs/cli/commands/lint/" target="_blank" rel="noopener noreferrer">validate your schemas</a>! openapi-typescript will err on invalid schemas. | ||
Lastly, be sure to **run typechecking** in your project. This can be done by adding `tsc --noEmit` to your [npm scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts) like so: | ||
Lastly, be sure to **run typechecking** in your project. This can be done by adding `tsc --noEmit` to your <a href="https://docs.npmjs.com/cli/v9/using-npm/scripts" target="_blank" rel="noopener noreferrer">npm scripts</a> like so: | ||
```json | ||
@@ -88,5 +88,7 @@ { | ||
> **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. | ||
> **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. | ||
## Usage | ||
## Basic usage | ||
@@ -125,2 +127,2 @@ The best part about using openapi-fetch over oldschool codegen is no documentation needed. openapi-fetch encourages using your existing OpenAPI documentation rather than trying to find what function to import, or what parameters that function wants: | ||
[View Docs](https://openapi-ts.dev/openapi-fetch/) | ||
[View Docs](https://openapi-ts.dev/openapi-fetch/) |
@@ -128,4 +128,2 @@ import type { | ||
export interface MiddlewareCallbackParams { | ||
/** Final URL for this request */ | ||
readonly url: string; | ||
/** Current Request object */ | ||
@@ -173,5 +171,3 @@ request: Request; | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): { | ||
export interface Client<Paths extends {}, Media extends MediaType = MediaType> { | ||
/** Call a GET endpoint */ | ||
@@ -197,4 +193,8 @@ GET: ClientMethod<Paths, "get", Media>; | ||
eject(...middleware: Middleware[]): void; | ||
}; | ||
} | ||
export default function createClient<Paths extends {}, Media extends MediaType = MediaType>( | ||
clientOptions?: ClientOptions, | ||
): Client<Paths, Media>; | ||
/** Serialize primitive params to string */ | ||
@@ -201,0 +201,0 @@ export declare function serializePrimitiveParam( |
@@ -87,7 +87,7 @@ // settings & const | ||
requestInit.body = bodySerializer(requestInit.body); | ||
// remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression | ||
if (requestInit.body instanceof FormData) { | ||
requestInit.headers.delete("Content-Type"); | ||
} | ||
} | ||
// remove `Content-Type` if serialized body is FormData; browser will correctly set Content-Type & boundary expression | ||
if (requestInit.body instanceof FormData) { | ||
requestInit.headers.delete("Content-Type"); | ||
} | ||
@@ -94,0 +94,0 @@ let id; |
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
121
115192
13
2021
+ Addedopenapi-typescript-helpers@0.0.10(transitive)
- Removedopenapi-typescript-helpers@0.0.9(transitive)