fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #2123 from hey-api/feat/fetch-response-style

feat: add responseStyle option to Fetch client

authored by

Lubos and committed by
GitHub
3dadecba 5553892e

+398 -235
+7
.changeset/warm-clocks-shave.md
··· 1 + --- 2 + '@hey-api/openapi-ts': minor 3 + --- 4 + 5 + feat(sdk): add responseStyle option 6 + 7 + **BREAKING**: Update your client to the latest version.
+7
.changeset/yellow-boats-think.md
··· 1 + --- 2 + '@hey-api/client-fetch': minor 3 + --- 4 + 5 + feat: add responseStyle option 6 + 7 + **BREAKING**: Update `@hey-api/openapi-ts` to the latest version.
+25 -17
packages/client-fetch/src/client.ts
··· 31 31 RequestOptions 32 32 >(); 33 33 34 - // @ts-expect-error 35 34 const request: Client['request'] = async (options) => { 36 35 const opts = { 37 36 ..._config, ··· 91 90 response.status === 204 || 92 91 response.headers.get('Content-Length') === '0' 93 92 ) { 94 - return { 95 - data: {}, 96 - ...result, 97 - }; 93 + return opts.responseStyle === 'data' 94 + ? {} 95 + : { 96 + data: {}, 97 + ...result, 98 + }; 98 99 } 99 100 100 101 const parseAs = ··· 103 104 : opts.parseAs) ?? 'json'; 104 105 105 106 if (parseAs === 'stream') { 106 - return { 107 - data: response.body, 108 - ...result, 109 - }; 107 + return opts.responseStyle === 'data' 108 + ? response.body 109 + : { 110 + data: response.body, 111 + ...result, 112 + }; 110 113 } 111 114 112 115 let data = await response[parseAs](); ··· 120 123 } 121 124 } 122 125 123 - return { 124 - data, 125 - ...result, 126 - }; 126 + return opts.responseStyle === 'data' 127 + ? data 128 + : { 129 + data, 130 + ...result, 131 + }; 127 132 } 128 133 129 134 let error = await response.text(); ··· 148 153 throw finalError; 149 154 } 150 155 151 - return { 152 - error: finalError, 153 - ...result, 154 - }; 156 + // TODO: we probably want to return error and improve types 157 + return opts.responseStyle === 'data' 158 + ? undefined 159 + : { 160 + error: finalError, 161 + ...result, 162 + }; 155 163 }; 156 164 157 165 return {
+1
packages/client-fetch/src/index.ts
··· 8 8 OptionsLegacyParser, 9 9 RequestOptions, 10 10 RequestResult, 11 + ResponseStyle, 11 12 TDataShape, 12 13 } from './types'; 13 14 export { createConfig } from './utils';
+70 -30
packages/client-fetch/src/types.ts
··· 6 6 7 7 import type { Middleware } from './utils'; 8 8 9 + export type ResponseStyle = 'data' | 'fields'; 10 + 9 11 export interface Config<T extends ClientOptions = ClientOptions> 10 12 extends Omit<RequestInit, 'body' | 'headers' | 'method'>, 11 13 CoreConfig { ··· 37 39 */ 38 40 parseAs?: Exclude<keyof Body, 'body' | 'bodyUsed'> | 'auto' | 'stream'; 39 41 /** 42 + * Should we return only data or multiple fields (data, error, response, etc.)? 43 + * 44 + * @default 'fields' 45 + */ 46 + responseStyle?: ResponseStyle; 47 + /** 40 48 * Throw an error instead of returning it in the response? 41 49 * 42 50 * @default false ··· 45 53 } 46 54 47 55 export interface RequestOptions< 56 + TResponseStyle extends ResponseStyle = 'fields', 48 57 ThrowOnError extends boolean = boolean, 49 58 Url extends string = string, 50 59 > extends Config<{ 60 + responseStyle: TResponseStyle; 51 61 throwOnError: ThrowOnError; 52 62 }> { 53 63 /** ··· 69 79 TData = unknown, 70 80 TError = unknown, 71 81 ThrowOnError extends boolean = boolean, 82 + TResponseStyle extends ResponseStyle = 'fields', 72 83 > = ThrowOnError extends true 73 - ? Promise<{ 74 - data: TData extends Record<string, unknown> ? TData[keyof TData] : TData; 75 - request: Request; 76 - response: Response; 77 - }> 78 - : Promise< 79 - ( 80 - | { 84 + ? Promise< 85 + TResponseStyle extends 'data' 86 + ? TData extends Record<string, unknown> 87 + ? TData[keyof TData] 88 + : TData 89 + : { 81 90 data: TData extends Record<string, unknown> 82 91 ? TData[keyof TData] 83 92 : TData; 84 - error: undefined; 93 + request: Request; 94 + response: Response; 85 95 } 86 - | { 87 - data: undefined; 88 - error: TError extends Record<string, unknown> 89 - ? TError[keyof TError] 90 - : TError; 96 + > 97 + : Promise< 98 + TResponseStyle extends 'data' 99 + ? 100 + | (TData extends Record<string, unknown> 101 + ? TData[keyof TData] 102 + : TData) 103 + | undefined 104 + : ( 105 + | { 106 + data: TData extends Record<string, unknown> 107 + ? TData[keyof TData] 108 + : TData; 109 + error: undefined; 110 + } 111 + | { 112 + data: undefined; 113 + error: TError extends Record<string, unknown> 114 + ? TError[keyof TError] 115 + : TError; 116 + } 117 + ) & { 118 + request: Request; 119 + response: Response; 91 120 } 92 - ) & { 93 - request: Request; 94 - response: Response; 95 - } 96 121 >; 97 122 98 123 export interface ClientOptions { 99 124 baseUrl?: string; 125 + responseStyle?: ResponseStyle; 100 126 throwOnError?: boolean; 101 127 } 102 128 ··· 104 130 TData = unknown, 105 131 TError = unknown, 106 132 ThrowOnError extends boolean = false, 133 + TResponseStyle extends ResponseStyle = 'fields', 107 134 >( 108 - options: Omit<RequestOptions<ThrowOnError>, 'method'>, 109 - ) => RequestResult<TData, TError, ThrowOnError>; 135 + options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'>, 136 + ) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 110 137 111 138 type RequestFn = < 112 139 TData = unknown, 113 140 TError = unknown, 114 141 ThrowOnError extends boolean = false, 142 + TResponseStyle extends ResponseStyle = 'fields', 115 143 >( 116 - options: Omit<RequestOptions<ThrowOnError>, 'method'> & 117 - Pick<Required<RequestOptions<ThrowOnError>>, 'method'>, 118 - ) => RequestResult<TData, TError, ThrowOnError>; 144 + options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'> & 145 + Pick<Required<RequestOptions<TResponseStyle, ThrowOnError>>, 'method'>, 146 + ) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 119 147 120 148 type BuildUrlFn = < 121 149 TData extends { ··· 157 185 export type Options< 158 186 TData extends TDataShape = TDataShape, 159 187 ThrowOnError extends boolean = boolean, 160 - > = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & 188 + TResponseStyle extends ResponseStyle = 'fields', 189 + > = OmitKeys< 190 + RequestOptions<TResponseStyle, ThrowOnError>, 191 + 'body' | 'path' | 'query' | 'url' 192 + > & 161 193 Omit<TData, 'url'>; 162 194 163 195 export type OptionsLegacyParser< 164 196 TData = unknown, 165 197 ThrowOnError extends boolean = boolean, 198 + TResponseStyle extends ResponseStyle = 'fields', 166 199 > = TData extends { body?: any } 167 200 ? TData extends { headers?: any } 168 - ? OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'headers' | 'url'> & TData 169 - : OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'url'> & 201 + ? OmitKeys< 202 + RequestOptions<TResponseStyle, ThrowOnError>, 203 + 'body' | 'headers' | 'url' 204 + > & 205 + TData 206 + : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'url'> & 170 207 TData & 171 - Pick<RequestOptions<ThrowOnError>, 'headers'> 208 + Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'headers'> 172 209 : TData extends { headers?: any } 173 - ? OmitKeys<RequestOptions<ThrowOnError>, 'headers' | 'url'> & 210 + ? OmitKeys< 211 + RequestOptions<TResponseStyle, ThrowOnError>, 212 + 'headers' | 'url' 213 + > & 174 214 TData & 175 - Pick<RequestOptions<ThrowOnError>, 'body'> 176 - : OmitKeys<RequestOptions<ThrowOnError>, 'url'> & TData; 215 + Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'body'> 216 + : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'url'> & TData;
+1 -1
packages/openapi-ts-tests/test/__snapshots__/3.1.x/clients/@hey-api/client-fetch/bundle/client/index.cjs
··· 1 - 'use strict';var j=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));},I=(t,r,e)=>{typeof e=="string"?t.append(r,e):t.append(r,JSON.stringify(e));},k={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}},R={bodySerializer:t=>JSON.stringify(t,(r,e)=>typeof e=="bigint"?e.toString():e)},$={bodySerializer:t=>{let r=new URLSearchParams;return Object.entries(t).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>I(r,e,a)):I(r,e,i));}),r.toString()}},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 "&"}},O=({allowReserved:t,explode:r,name:e,style:i,value:a})=>{if(!r){let n=(t?a:a.map(l=>encodeURIComponent(l))).join(_(i));switch(i){case "label":return `.${n}`;case "matrix":return `;${e}=${n}`;case "simple":return n;default:return `${e}=${n}`}}let o=U(i),s=a.map(n=>i==="label"||i==="simple"?t?n:encodeURIComponent(n):y({allowReserved:t,name:e,value:n})).join(o);return i==="label"||i==="matrix"?o+s:s},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)}`},q=({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(([f,p])=>{n=[...n,f,t?p:encodeURIComponent(p)];});let l=n.join(",");switch(i){case "form":return `${e}=${l}`;case "label":return `.${l}`;case "matrix":return `;${e}=${l}`;default:return l}}let o=D(i),s=Object.entries(a).map(([n,l])=>y({allowReserved:t,name:i==="deepObject"?`${e}[${n}]`:n,value:l})).join(o);return i==="label"||i==="matrix"?o+s:s};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,s=a.substring(1,a.length-1),n="simple";s.endsWith("*")&&(o=true,s=s.substring(0,s.length-1)),s.startsWith(".")?(s=s.substring(1),n="label"):s.startsWith(";")&&(s=s.substring(1),n="matrix");let l=t[s];if(l==null)continue;if(Array.isArray(l)){e=e.replace(a,O({explode:o,name:s,style:n,value:l}));continue}if(typeof l=="object"){e=e.replace(a,q({explode:o,name:s,style:n,value:l}));continue}if(n==="matrix"){e=e.replace(a,`;${y({name:s,value:l})}`);continue}let f=encodeURIComponent(n==="label"?`.${l}`:l);e=e.replace(a,f);}return e},A=({allowReserved:t,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let s in a){let n=a[s];if(n!=null)if(Array.isArray(n)){let l=O({allowReserved:t,explode:true,name:s,style:"form",value:n,...r});l&&o.push(l);}else if(typeof n=="object"){let l=q({allowReserved:t,explode:true,name:s,style:"deepObject",value:n,...e});l&&o.push(l);}else {let l=y({allowReserved:t,name:s,value:n});l&&o.push(l);}}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"}},E=async({security:t,...r})=>{for(let e of t){let i=await j(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 "cookie":r.headers.append("Cookie",`${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:A(t.querySerializer),url:t.url}),W=({baseUrl:t,path:r,query:e,querySerializer:i,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,s=(t??"")+o;r&&(s=B({path:r,url:s}));let n=e?i(e):"";return n.startsWith("?")&&(n=n.substring(1)),n&&(s+=`?${n}`),s},x=(t,r)=>{let e={...t,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=C(t.headers,r.headers),e},C=(...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 s of o)r.append(a,s);else o!==void 0&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},h=class{_fns;constructor(){this._fns=[];}clear(){this._fns=[];}getInterceptorIndex(r){return typeof r=="number"?this._fns[r]?r:-1:this._fns.indexOf(r)}exists(r){let e=this.getInterceptorIndex(r);return !!this._fns[e]}eject(r){let e=this.getInterceptorIndex(r);this._fns[e]&&(this._fns[e]=null);}update(r,e){let i=this.getInterceptorIndex(r);return this._fns[i]?(this._fns[i]=e,r):false}use(r){return this._fns=[...this._fns,r],this._fns.length-1}},v=()=>({error:new h,request:new h,response:new h}),N=A({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),Q={"Content-Type":"application/json"},w=(t={})=>({...R,headers:Q,parseAs:"auto",querySerializer:N,...t});var J=(t={})=>{let r=x(w(),t),e=()=>({...r}),i=s=>(r=x(r,s),e()),a=v(),o=async s=>{let n={...r,...s,fetch:s.fetch??r.fetch??globalThis.fetch,headers:C(r.headers,s.headers)};n.security&&await E({...n,security:n.security}),n.body&&n.bodySerializer&&(n.body=n.bodySerializer(n.body)),(n.body===void 0||n.body==="")&&n.headers.delete("Content-Type");let l=S(n),f={redirect:"follow",...n},p=new Request(l,f);for(let c of a.request._fns)c&&(p=await c(p,n));let T=n.fetch,u=await T(p);for(let c of a.response._fns)c&&(u=await c(u,p,n));let m={request:p,response:u};if(u.ok){if(u.status===204||u.headers.get("Content-Length")==="0")return {data:{},...m};let c=(n.parseAs==="auto"?P(u.headers.get("Content-Type")):n.parseAs)??"json";if(c==="stream")return {data:u.body,...m};let b=await u[c]();return c==="json"&&(n.responseValidator&&await n.responseValidator(b),n.responseTransformer&&(b=await n.responseTransformer(b))),{data:b,...m}}let g=await u.text();try{g=JSON.parse(g);}catch{}let d=g;for(let c of a.error._fns)c&&(d=await c(g,u,p,n));if(d=d||{},n.throwOnError)throw d;return {error:d,...m}};return {buildUrl:S,connect:s=>o({...s,method:"CONNECT"}),delete:s=>o({...s,method:"DELETE"}),get:s=>o({...s,method:"GET"}),getConfig:e,head:s=>o({...s,method:"HEAD"}),interceptors:a,options:s=>o({...s,method:"OPTIONS"}),patch:s=>o({...s,method:"PATCH"}),post:s=>o({...s,method:"POST"}),put:s=>o({...s,method:"PUT"}),request:o,setConfig:i,trace:s=>o({...s,method:"TRACE"})}};exports.createClient=J;exports.createConfig=w;exports.formDataBodySerializer=k;exports.jsonBodySerializer=R;exports.urlSearchParamsBodySerializer=$;//# sourceMappingURL=index.cjs.map 1 + 'use strict';var j=async(s,r)=>{let e=typeof r=="function"?await r(s):r;if(e)return s.scheme==="bearer"?`Bearer ${e}`:s.scheme==="basic"?`Basic ${btoa(e)}`:e},z=(s,r,e)=>{typeof e=="string"||e instanceof Blob?s.append(r,e):s.append(r,JSON.stringify(e));},I=(s,r,e)=>{typeof e=="string"?s.append(r,e):s.append(r,JSON.stringify(e));},k={bodySerializer:s=>{let r=new FormData;return Object.entries(s).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>z(r,e,a)):z(r,e,i));}),r}},R={bodySerializer:s=>JSON.stringify(s,(r,e)=>typeof e=="bigint"?e.toString():e)},$={bodySerializer:s=>{let r=new URLSearchParams;return Object.entries(s).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(a=>I(r,e,a)):I(r,e,i));}),r.toString()}},U=s=>{switch(s){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},_=s=>{switch(s){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},D=s=>{switch(s){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},O=({allowReserved:s,explode:r,name:e,style:i,value:a})=>{if(!r){let t=(s?a:a.map(l=>encodeURIComponent(l))).join(_(i));switch(i){case "label":return `.${t}`;case "matrix":return `;${e}=${t}`;case "simple":return t;default:return `${e}=${t}`}}let o=U(i),n=a.map(t=>i==="label"||i==="simple"?s?t:encodeURIComponent(t):h({allowReserved:s,name:e,value:t})).join(o);return i==="label"||i==="matrix"?o+n:n},h=({allowReserved:s,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}=${s?e:encodeURIComponent(e)}`},S=({allowReserved:s,explode:r,name:e,style:i,value:a})=>{if(a instanceof Date)return `${e}=${a.toISOString()}`;if(i!=="deepObject"&&!r){let t=[];Object.entries(a).forEach(([f,p])=>{t=[...t,f,s?p:encodeURIComponent(p)];});let l=t.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(([t,l])=>h({allowReserved:s,name:i==="deepObject"?`${e}[${t}]`:t,value:l})).join(o);return i==="label"||i==="matrix"?o+n:n};var H=/\{[^{}]+\}/g,B=({path:s,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),t="simple";n.endsWith("*")&&(o=true,n=n.substring(0,n.length-1)),n.startsWith(".")?(n=n.substring(1),t="label"):n.startsWith(";")&&(n=n.substring(1),t="matrix");let l=s[n];if(l==null)continue;if(Array.isArray(l)){e=e.replace(a,O({explode:o,name:n,style:t,value:l}));continue}if(typeof l=="object"){e=e.replace(a,S({explode:o,name:n,style:t,value:l}));continue}if(t==="matrix"){e=e.replace(a,`;${h({name:n,value:l})}`);continue}let f=encodeURIComponent(t==="label"?`.${l}`:l);e=e.replace(a,f);}return e},A=({allowReserved:s,array:r,object:e}={})=>a=>{let o=[];if(a&&typeof a=="object")for(let n in a){let t=a[n];if(t!=null)if(Array.isArray(t)){let l=O({allowReserved:s,explode:true,name:n,style:"form",value:t,...r});l&&o.push(l);}else if(typeof t=="object"){let l=S({allowReserved:s,explode:true,name:n,style:"deepObject",value:t,...e});l&&o.push(l);}else {let l=h({allowReserved:s,name:n,value:t});l&&o.push(l);}}return o.join("&")},P=s=>{if(!s)return "stream";let r=s.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"}},E=async({security:s,...r})=>{for(let e of s){let i=await j(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 "cookie":r.headers.append("Cookie",`${a}=${i}`);break;case "header":default:r.headers.set(a,i);break}return}},q=s=>W({baseUrl:s.baseUrl,path:s.path,query:s.query,querySerializer:typeof s.querySerializer=="function"?s.querySerializer:A(s.querySerializer),url:s.url}),W=({baseUrl:s,path:r,query:e,querySerializer:i,url:a})=>{let o=a.startsWith("/")?a:`/${a}`,n=(s??"")+o;r&&(n=B({path:r,url:n}));let t=e?i(e):"";return t.startsWith("?")&&(t=t.substring(1)),t&&(n+=`?${t}`),n},x=(s,r)=>{let e={...s,...r};return e.baseUrl?.endsWith("/")&&(e.baseUrl=e.baseUrl.substring(0,e.baseUrl.length-1)),e.headers=C(s.headers,r.headers),e},C=(...s)=>{let r=new Headers;for(let e of s){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!==void 0&&r.set(a,typeof o=="object"?JSON.stringify(o):o);}return r},m=class{_fns;constructor(){this._fns=[];}clear(){this._fns=[];}getInterceptorIndex(r){return typeof r=="number"?this._fns[r]?r:-1:this._fns.indexOf(r)}exists(r){let e=this.getInterceptorIndex(r);return !!this._fns[e]}eject(r){let e=this.getInterceptorIndex(r);this._fns[e]&&(this._fns[e]=null);}update(r,e){let i=this.getInterceptorIndex(r);return this._fns[i]?(this._fns[i]=e,r):false}use(r){return this._fns=[...this._fns,r],this._fns.length-1}},v=()=>({error:new m,request:new m,response:new m}),N=A({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),Q={"Content-Type":"application/json"},w=(s={})=>({...R,headers:Q,parseAs:"auto",querySerializer:N,...s});var J=(s={})=>{let r=x(w(),s),e=()=>({...r}),i=n=>(r=x(r,n),e()),a=v(),o=async n=>{let t={...r,...n,fetch:n.fetch??r.fetch??globalThis.fetch,headers:C(r.headers,n.headers)};t.security&&await E({...t,security:t.security}),t.body&&t.bodySerializer&&(t.body=t.bodySerializer(t.body)),(t.body===void 0||t.body==="")&&t.headers.delete("Content-Type");let l=q(t),f={redirect:"follow",...t},p=new Request(l,f);for(let u of a.request._fns)u&&(p=await u(p,t));let T=t.fetch,c=await T(p);for(let u of a.response._fns)u&&(c=await u(c,p,t));let g={request:p,response:c};if(c.ok){if(c.status===204||c.headers.get("Content-Length")==="0")return t.responseStyle==="data"?{}:{data:{},...g};let u=(t.parseAs==="auto"?P(c.headers.get("Content-Type")):t.parseAs)??"json";if(u==="stream")return t.responseStyle==="data"?c.body:{data:c.body,...g};let y=await c[u]();return u==="json"&&(t.responseValidator&&await t.responseValidator(y),t.responseTransformer&&(y=await t.responseTransformer(y))),t.responseStyle==="data"?y:{data:y,...g}}let b=await c.text();try{b=JSON.parse(b);}catch{}let d=b;for(let u of a.error._fns)u&&(d=await u(b,c,p,t));if(d=d||{},t.throwOnError)throw d;return t.responseStyle==="data"?void 0:{error:d,...g}};return {buildUrl:q,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"})}};exports.createClient=J;exports.createConfig=w;exports.formDataBodySerializer=k;exports.jsonBodySerializer=R;exports.urlSearchParamsBodySerializer=$;//# sourceMappingURL=index.cjs.map 2 2 //# sourceMappingURL=index.cjs.map
+19 -10
packages/openapi-ts-tests/test/__snapshots__/3.1.x/clients/@hey-api/client-fetch/bundle/client/index.d.cts
··· 128 128 } 129 129 declare const createConfig: <T extends ClientOptions = ClientOptions>(override?: Config<Omit<ClientOptions, keyof T> & T>) => Config<Omit<ClientOptions, keyof T> & T>; 130 130 131 + type ResponseStyle = 'data' | 'fields'; 131 132 interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config$1 { 132 133 /** 133 134 * Base URL for all requests made by this client. ··· 157 158 */ 158 159 parseAs?: Exclude<keyof Body, 'body' | 'bodyUsed'> | 'auto' | 'stream'; 159 160 /** 161 + * Should we return only data or multiple fields (data, error, response, etc.)? 162 + * 163 + * @default 'fields' 164 + */ 165 + responseStyle?: ResponseStyle; 166 + /** 160 167 * Throw an error instead of returning it in the response? 161 168 * 162 169 * @default false 163 170 */ 164 171 throwOnError?: T['throwOnError']; 165 172 } 166 - interface RequestOptions<ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{ 173 + interface RequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{ 174 + responseStyle: TResponseStyle; 167 175 throwOnError: ThrowOnError; 168 176 }> { 169 177 /** ··· 180 188 security?: ReadonlyArray<Auth>; 181 189 url: Url; 182 190 } 183 - type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean> = ThrowOnError extends true ? Promise<{ 191 + type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : { 184 192 data: TData extends Record<string, unknown> ? TData[keyof TData] : TData; 185 193 request: Request; 186 194 response: Response; 187 - }> : Promise<({ 195 + }> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({ 188 196 data: TData extends Record<string, unknown> ? TData[keyof TData] : TData; 189 197 error: undefined; 190 198 } | { ··· 196 204 }>; 197 205 interface ClientOptions { 198 206 baseUrl?: string; 207 + responseStyle?: ResponseStyle; 199 208 throwOnError?: boolean; 200 209 } 201 - type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>(options: Omit<RequestOptions<ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError>; 202 - type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>(options: Omit<RequestOptions<ThrowOnError>, 'method'> & Pick<Required<RequestOptions<ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError>; 210 + type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 211 + type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 203 212 type BuildUrlFn = <TData extends { 204 213 body?: unknown; 205 214 path?: Record<string, unknown>; ··· 226 235 url: string; 227 236 } 228 237 type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; 229 - type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; 230 - type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean> = TData extends { 238 + type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; 239 + type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = TData extends { 231 240 body?: any; 232 241 } ? TData extends { 233 242 headers?: any; 234 - } ? OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'headers' | 'url'> & TData : OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'url'> & TData & Pick<RequestOptions<ThrowOnError>, 'headers'> : TData extends { 243 + } ? OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'headers' | 'url'> & TData : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'url'> & TData & Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'headers'> : TData extends { 235 244 headers?: any; 236 - } ? OmitKeys<RequestOptions<ThrowOnError>, 'headers' | 'url'> & TData & Pick<RequestOptions<ThrowOnError>, 'body'> : OmitKeys<RequestOptions<ThrowOnError>, 'url'> & TData; 245 + } ? OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'headers' | 'url'> & TData & Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'body'> : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'url'> & TData; 237 246 238 247 declare const createClient: (config?: Config) => Client; 239 248 240 - export { type Auth, type Client, type ClientOptions, type Config, type CreateClientConfig, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, type TDataShape, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer }; 249 + export { type Auth, type Client, type ClientOptions, type Config, type CreateClientConfig, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, type ResponseStyle, type TDataShape, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer };
+19 -10
packages/openapi-ts-tests/test/__snapshots__/3.1.x/clients/@hey-api/client-fetch/bundle/client/index.d.ts
··· 128 128 } 129 129 declare const createConfig: <T extends ClientOptions = ClientOptions>(override?: Config<Omit<ClientOptions, keyof T> & T>) => Config<Omit<ClientOptions, keyof T> & T>; 130 130 131 + type ResponseStyle = 'data' | 'fields'; 131 132 interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config$1 { 132 133 /** 133 134 * Base URL for all requests made by this client. ··· 157 158 */ 158 159 parseAs?: Exclude<keyof Body, 'body' | 'bodyUsed'> | 'auto' | 'stream'; 159 160 /** 161 + * Should we return only data or multiple fields (data, error, response, etc.)? 162 + * 163 + * @default 'fields' 164 + */ 165 + responseStyle?: ResponseStyle; 166 + /** 160 167 * Throw an error instead of returning it in the response? 161 168 * 162 169 * @default false 163 170 */ 164 171 throwOnError?: T['throwOnError']; 165 172 } 166 - interface RequestOptions<ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{ 173 + interface RequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{ 174 + responseStyle: TResponseStyle; 167 175 throwOnError: ThrowOnError; 168 176 }> { 169 177 /** ··· 180 188 security?: ReadonlyArray<Auth>; 181 189 url: Url; 182 190 } 183 - type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean> = ThrowOnError extends true ? Promise<{ 191 + type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : { 184 192 data: TData extends Record<string, unknown> ? TData[keyof TData] : TData; 185 193 request: Request; 186 194 response: Response; 187 - }> : Promise<({ 195 + }> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({ 188 196 data: TData extends Record<string, unknown> ? TData[keyof TData] : TData; 189 197 error: undefined; 190 198 } | { ··· 196 204 }>; 197 205 interface ClientOptions { 198 206 baseUrl?: string; 207 + responseStyle?: ResponseStyle; 199 208 throwOnError?: boolean; 200 209 } 201 - type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>(options: Omit<RequestOptions<ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError>; 202 - type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false>(options: Omit<RequestOptions<ThrowOnError>, 'method'> & Pick<Required<RequestOptions<ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError>; 210 + type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 211 + type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>; 203 212 type BuildUrlFn = <TData extends { 204 213 body?: unknown; 205 214 path?: Record<string, unknown>; ··· 226 235 url: string; 227 236 } 228 237 type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>; 229 - type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; 230 - type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean> = TData extends { 238 + type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & Omit<TData, 'url'>; 239 + type OptionsLegacyParser<TData = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = TData extends { 231 240 body?: any; 232 241 } ? TData extends { 233 242 headers?: any; 234 - } ? OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'headers' | 'url'> & TData : OmitKeys<RequestOptions<ThrowOnError>, 'body' | 'url'> & TData & Pick<RequestOptions<ThrowOnError>, 'headers'> : TData extends { 243 + } ? OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'headers' | 'url'> & TData : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'body' | 'url'> & TData & Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'headers'> : TData extends { 235 244 headers?: any; 236 - } ? OmitKeys<RequestOptions<ThrowOnError>, 'headers' | 'url'> & TData & Pick<RequestOptions<ThrowOnError>, 'body'> : OmitKeys<RequestOptions<ThrowOnError>, 'url'> & TData; 245 + } ? OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'headers' | 'url'> & TData & Pick<RequestOptions<TResponseStyle, ThrowOnError>, 'body'> : OmitKeys<RequestOptions<TResponseStyle, ThrowOnError>, 'url'> & TData; 237 246 238 247 declare const createClient: (config?: Config) => Client; 239 248 240 - export { type Auth, type Client, type ClientOptions, type Config, type CreateClientConfig, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, type TDataShape, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer }; 249 + export { type Auth, type Client, type ClientOptions, type Config, type CreateClientConfig, type Options, type OptionsLegacyParser, type QuerySerializerOptions, type RequestOptions, type RequestResult, type ResponseStyle, type TDataShape, createClient, createConfig, formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer };
+5 -3
packages/openapi-ts-tests/test/openapi-ts.config.ts
··· 51 51 // 'invalid', 52 52 // 'servers-entry.yaml', 53 53 // ), 54 - path: path.resolve(__dirname, 'spec', '3.1.x', 'type-format.yaml'), 54 + path: path.resolve(__dirname, 'spec', '3.1.x', 'full.json'), 55 55 // path: 'http://localhost:4000/', 56 56 // path: 'https://get.heyapi.dev/', 57 57 // path: 'https://get.heyapi.dev/hey-api/backend?branch=main&version=1.0.0', ··· 93 93 // bundle: true, 94 94 // bundleSource_EXPERIMENTAL: true, 95 95 // exportFromIndex: true, 96 - name: '@hey-api/client-fetch', 96 + name: '@hey-api/client-axios', 97 + // name: '@hey-api/client-fetch', 97 98 // strictBaseUrl: true, 98 99 }, 99 100 { ··· 107 108 // include... 108 109 name: '@hey-api/sdk', 109 110 // operationId: false, 111 + responseStyle: 'data', 110 112 // serviceNameBuilder: '{{name}}', 111 113 // throwOnError: true, 112 114 // transformer: '@hey-api/transformers', ··· 135 137 }, 136 138 { 137 139 exportFromIndex: true, 138 - // name: '@tanstack/vue-query', 140 + name: '@tanstack/react-query', 139 141 }, 140 142 { 141 143 // comments: false,
+4 -1
packages/openapi-ts/src/compiler/return.ts
··· 33 33 /** 34 34 * List of function types. 35 35 */ 36 - types?: string[]; 36 + types?: ReadonlyArray<string | ts.StringLiteral>; 37 37 }) => { 38 38 const typeArguments = types.map((type) => 39 + // this works with string literals too despite throwing a type error. 40 + // should be probably fixed at some point... 41 + // @ts-expect-error 39 42 createTypeReferenceNode({ typeName: type }), 40 43 ); 41 44 const argumentsArray = args
+6
packages/openapi-ts/src/plugins/@hey-api/sdk/config.ts
··· 38 38 39 39 context.ensureDependency(config.validator); 40 40 } 41 + 42 + // TODO: add responseStyle field to all clients 43 + if (config.client !== '@hey-api/client-fetch') { 44 + config.responseStyle = 'fields'; 45 + } 41 46 }, 42 47 asClass: false, 43 48 auth: true, ··· 47 52 operationId: true, 48 53 output: 'sdk', 49 54 response: 'body', 55 + responseStyle: 'fields', 50 56 serviceNameBuilder: '{{name}}Service', 51 57 }; 52 58
+24 -8
packages/openapi-ts/src/plugins/@hey-api/sdk/plugin.ts
··· 417 417 }); 418 418 } 419 419 420 + if (plugin.responseStyle === 'data') { 421 + requestOptions.push({ 422 + key: 'responseStyle', 423 + value: plugin.responseStyle, 424 + }); 425 + } 426 + 420 427 requestOptions.push({ 421 428 key: 'url', 422 429 value: operation.path, ··· 474 481 name: 'client', 475 482 }); 476 483 484 + const types: Array<string | ts.StringLiteral> = []; 485 + if (isNuxtClient) { 486 + types.push( 487 + nuxtTypeComposable, 488 + `${responseType} | ${nuxtTypeDefault}`, 489 + errorType, 490 + nuxtTypeDefault, 491 + ); 492 + } else { 493 + types.push(responseType, errorType, 'ThrowOnError'); 494 + } 495 + 496 + if (plugin.responseStyle === 'data') { 497 + types.push(compiler.stringLiteral({ text: plugin.responseStyle })); 498 + } 499 + 477 500 return [ 478 501 compiler.returnFunctionCall({ 479 502 args: [ ··· 492 515 : optionsClient, 493 516 name: compiler.identifier({ text: operation.method }), 494 517 }), 495 - types: isNuxtClient 496 - ? [ 497 - nuxtTypeComposable, 498 - `${responseType} | ${nuxtTypeDefault}`, 499 - errorType, 500 - nuxtTypeDefault, 501 - ] 502 - : [responseType, errorType, 'ThrowOnError'], 518 + types, 503 519 }), 504 520 ]; 505 521 };
+8
packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts
··· 70 70 */ 71 71 output?: string; 72 72 /** 73 + * **This feature works only with the Fetch client** 74 + * 75 + * Should we return only data or multiple fields (data, error, response, etc.)? 76 + * 77 + * @default 'fields' 78 + */ 79 + responseStyle?: 'data' | 'fields'; 80 + /** 73 81 * Customize the generated service class names. The name variable is 74 82 * obtained from your OpenAPI specification tags. 75 83 *
+101 -86
packages/openapi-ts/src/plugins/@tanstack/query-core/infiniteQueryOptions.ts
··· 332 332 namespace: 'value', 333 333 }); 334 334 335 + const awaitSdkExpression = compiler.awaitExpression({ 336 + expression: compiler.callExpression({ 337 + functionName: queryFn, 338 + parameters: [ 339 + compiler.objectExpression({ 340 + multiLine: true, 341 + obj: [ 342 + { 343 + spread: 'options', 344 + }, 345 + { 346 + spread: 'params', 347 + }, 348 + { 349 + key: 'signal', 350 + shorthand: true, 351 + value: compiler.identifier({ 352 + text: 'signal', 353 + }), 354 + }, 355 + { 356 + key: 'throwOnError', 357 + value: true, 358 + }, 359 + ], 360 + }), 361 + ], 362 + }), 363 + }); 364 + 365 + const statements: Array<ts.Statement> = [ 366 + compiler.constVariable({ 367 + comment: [ 368 + { 369 + jsdoc: false, 370 + lines: ['@ts-ignore'], 371 + }, 372 + ], 373 + expression: compiler.conditionalExpression({ 374 + condition: compiler.binaryExpression({ 375 + left: compiler.typeOfExpression({ 376 + text: 'pageParam', 377 + }), 378 + operator: '===', 379 + right: compiler.ots.string('object'), 380 + }), 381 + whenFalse: compiler.objectExpression({ 382 + multiLine: true, 383 + obj: [ 384 + { 385 + key: pagination.in, 386 + value: compiler.objectExpression({ 387 + multiLine: true, 388 + obj: [ 389 + { 390 + key: pagination.name, 391 + value: compiler.identifier({ 392 + text: 'pageParam', 393 + }), 394 + }, 395 + ], 396 + }), 397 + }, 398 + ], 399 + }), 400 + whenTrue: compiler.identifier({ 401 + text: 'pageParam', 402 + }), 403 + }), 404 + name: 'page', 405 + typeName: typePageObjectParam, 406 + }), 407 + compiler.constVariable({ 408 + expression: compiler.callExpression({ 409 + functionName: createInfiniteParamsFn, 410 + parameters: ['queryKey', 'page'], 411 + }), 412 + name: 'params', 413 + }), 414 + ]; 415 + 416 + if (context.config.plugins['@hey-api/sdk']?.responseStyle === 'data') { 417 + statements.push( 418 + compiler.returnVariable({ 419 + expression: awaitSdkExpression, 420 + }), 421 + ); 422 + } else { 423 + statements.push( 424 + compiler.constVariable({ 425 + destructure: true, 426 + expression: awaitSdkExpression, 427 + name: 'data', 428 + }), 429 + compiler.returnVariable({ 430 + expression: 'data', 431 + }), 432 + ); 433 + } 434 + 335 435 const statement = compiler.constVariable({ 336 436 comment: plugin.comments 337 437 ? createOperationComment({ operation }) ··· 376 476 ], 377 477 }, 378 478 ], 379 - statements: [ 380 - compiler.constVariable({ 381 - comment: [ 382 - { 383 - jsdoc: false, 384 - lines: ['@ts-ignore'], 385 - }, 386 - ], 387 - expression: compiler.conditionalExpression({ 388 - condition: compiler.binaryExpression({ 389 - left: compiler.typeOfExpression({ 390 - text: 'pageParam', 391 - }), 392 - operator: '===', 393 - right: compiler.ots.string('object'), 394 - }), 395 - whenFalse: compiler.objectExpression({ 396 - multiLine: true, 397 - obj: [ 398 - { 399 - key: pagination.in, 400 - value: compiler.objectExpression({ 401 - multiLine: true, 402 - obj: [ 403 - { 404 - key: pagination.name, 405 - value: compiler.identifier({ 406 - text: 'pageParam', 407 - }), 408 - }, 409 - ], 410 - }), 411 - }, 412 - ], 413 - }), 414 - whenTrue: compiler.identifier({ 415 - text: 'pageParam', 416 - }), 417 - }), 418 - name: 'page', 419 - typeName: typePageObjectParam, 420 - }), 421 - compiler.constVariable({ 422 - expression: compiler.callExpression({ 423 - functionName: createInfiniteParamsFn, 424 - parameters: ['queryKey', 'page'], 425 - }), 426 - name: 'params', 427 - }), 428 - compiler.constVariable({ 429 - destructure: true, 430 - expression: compiler.awaitExpression({ 431 - expression: compiler.callExpression({ 432 - functionName: queryFn, 433 - parameters: [ 434 - compiler.objectExpression({ 435 - multiLine: true, 436 - obj: [ 437 - { 438 - spread: 'options', 439 - }, 440 - { 441 - spread: 'params', 442 - }, 443 - { 444 - key: 'signal', 445 - shorthand: true, 446 - value: compiler.identifier({ 447 - text: 'signal', 448 - }), 449 - }, 450 - { 451 - key: 'throwOnError', 452 - value: true, 453 - }, 454 - ], 455 - }), 456 - ], 457 - }), 458 - }), 459 - name: 'data', 460 - }), 461 - compiler.returnVariable({ 462 - expression: 'data', 463 - }), 464 - ], 479 + statements, 465 480 }), 466 481 }, 467 482 {
+47 -31
packages/openapi-ts/src/plugins/@tanstack/query-core/mutationOptions.ts
··· 1 + import type ts from 'typescript'; 2 + 1 3 import { compiler } from '../../../compiler'; 2 4 import type { IR } from '../../../ir/types'; 3 5 import { serviceFunctionIdentifier } from '../../@hey-api/sdk/plugin-legacy'; ··· 69 71 // TODO: better types syntax 70 72 const mutationType = `${mutationsType}<${typeResponse}, ${typeError.name}, ${typeData}>`; 71 73 74 + const awaitSdkExpression = compiler.awaitExpression({ 75 + expression: compiler.callExpression({ 76 + functionName: queryFn, 77 + parameters: [ 78 + compiler.objectExpression({ 79 + multiLine: true, 80 + obj: [ 81 + { 82 + spread: 'options', 83 + }, 84 + { 85 + spread: 'localOptions', 86 + }, 87 + { 88 + key: 'throwOnError', 89 + value: true, 90 + }, 91 + ], 92 + }), 93 + ], 94 + }), 95 + }); 96 + 97 + const statements: Array<ts.Statement> = []; 98 + 99 + if (context.config.plugins['@hey-api/sdk']?.responseStyle === 'data') { 100 + statements.push( 101 + compiler.returnVariable({ 102 + expression: awaitSdkExpression, 103 + }), 104 + ); 105 + } else { 106 + statements.push( 107 + compiler.constVariable({ 108 + destructure: true, 109 + expression: awaitSdkExpression, 110 + name: 'data', 111 + }), 112 + compiler.returnVariable({ 113 + expression: 'data', 114 + }), 115 + ); 116 + } 117 + 72 118 const expression = compiler.arrowFunction({ 73 119 parameters: [ 74 120 { ··· 92 138 name: 'localOptions', 93 139 }, 94 140 ], 95 - statements: [ 96 - compiler.constVariable({ 97 - destructure: true, 98 - expression: compiler.awaitExpression({ 99 - expression: compiler.callExpression({ 100 - functionName: queryFn, 101 - parameters: [ 102 - compiler.objectExpression({ 103 - multiLine: true, 104 - obj: [ 105 - { 106 - spread: 'options', 107 - }, 108 - { 109 - spread: 'localOptions', 110 - }, 111 - { 112 - key: 'throwOnError', 113 - value: true, 114 - }, 115 - ], 116 - }), 117 - ], 118 - }), 119 - }), 120 - name: 'data', 121 - }), 122 - compiler.returnVariable({ 123 - expression: 'data', 124 - }), 125 - ], 141 + statements, 126 142 }), 127 143 }, 128 144 ],
+54 -38
packages/openapi-ts/src/plugins/@tanstack/query-core/queryOptions.ts
··· 1 + import type ts from 'typescript'; 2 + 1 3 import { compiler } from '../../../compiler'; 2 4 import type { IR } from '../../../ir/types'; 3 5 import { serviceFunctionIdentifier } from '../../@hey-api/sdk/plugin-legacy'; ··· 89 91 namespace: 'value', 90 92 }); 91 93 94 + const awaitSdkExpression = compiler.awaitExpression({ 95 + expression: compiler.callExpression({ 96 + functionName: queryFn, 97 + parameters: [ 98 + compiler.objectExpression({ 99 + multiLine: true, 100 + obj: [ 101 + { 102 + spread: 'options', 103 + }, 104 + { 105 + spread: 'queryKey[0]', 106 + }, 107 + { 108 + key: 'signal', 109 + shorthand: true, 110 + value: compiler.identifier({ 111 + text: 'signal', 112 + }), 113 + }, 114 + { 115 + key: 'throwOnError', 116 + value: true, 117 + }, 118 + ], 119 + }), 120 + ], 121 + }), 122 + }); 123 + 124 + const statements: Array<ts.Statement> = []; 125 + 126 + if (context.config.plugins['@hey-api/sdk']?.responseStyle === 'data') { 127 + statements.push( 128 + compiler.returnVariable({ 129 + expression: awaitSdkExpression, 130 + }), 131 + ); 132 + } else { 133 + statements.push( 134 + compiler.constVariable({ 135 + destructure: true, 136 + expression: awaitSdkExpression, 137 + name: 'data', 138 + }), 139 + compiler.returnVariable({ 140 + expression: 'data', 141 + }), 142 + ); 143 + } 144 + 92 145 const statement = compiler.constVariable({ 93 146 comment: plugin.comments 94 147 ? createOperationComment({ operation }) ··· 124 177 ], 125 178 }, 126 179 ], 127 - statements: [ 128 - compiler.constVariable({ 129 - destructure: true, 130 - expression: compiler.awaitExpression({ 131 - expression: compiler.callExpression({ 132 - functionName: queryFn, 133 - parameters: [ 134 - compiler.objectExpression({ 135 - multiLine: true, 136 - obj: [ 137 - { 138 - spread: 'options', 139 - }, 140 - { 141 - spread: 'queryKey[0]', 142 - }, 143 - { 144 - key: 'signal', 145 - shorthand: true, 146 - value: compiler.identifier({ 147 - text: 'signal', 148 - }), 149 - }, 150 - { 151 - key: 'throwOnError', 152 - value: true, 153 - }, 154 - ], 155 - }), 156 - ], 157 - }), 158 - }), 159 - name: 'data', 160 - }), 161 - compiler.returnVariable({ 162 - expression: 'data', 163 - }), 164 - ], 180 + statements, 165 181 }), 166 182 }, 167 183 {