-
-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: handle nested values in formDataBodySerializer #1609
base: main
Are you sure you want to change the base?
Conversation
|
🦋 Changeset detectedLatest commit: 0d90910 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
...ges/openapi-ts/test/__snapshots__/3.1.x/clients/@hey-api/client-nuxt/bundle/client/index.cjs
Fixed
Show fixed
Hide fixed
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1609 +/- ##
=======================================
Coverage 57.16% 57.16%
=======================================
Files 189 189
Lines 25620 25620
Branches 1911 1911
=======================================
Hits 14646 14646
Misses 10965 10965
Partials 9 9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@hey-api/client-axios
@hey-api/client-fetch
@hey-api/client-next
@hey-api/client-nuxt
@hey-api/openapi-ts
commit: |
if (typeof value === 'string' || value instanceof Blob) { | ||
data.append(key, value); | ||
} else { | ||
data.append(key, JSON.stringify(value)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to warn when stringifying a non-JSON type. I ran into issues initially when passing a FileList
to a form, expecting it to be serialized as a blob array. Instead, it came out as {}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly I think that's more on us to handle properly
…/form-data-body-serializer
@@ -1,2 +1,2 @@ | |||
'use strict';var app=require('nuxt/app'),vue=require('vue');var E=async(r,t)=>{let e=typeof t=="function"?await t(r):t;if(e)return r.scheme==="bearer"?`Bearer ${e}`:r.scheme==="basic"?`Basic ${btoa(e)}`:e},U=(r,t,e)=>{typeof e=="string"||e instanceof Blob?r.append(t,e):r.append(t,JSON.stringify(e));},k=(r,t,e)=>{typeof e=="string"?r.append(t,e):r.append(t,JSON.stringify(e));},F={bodySerializer:r=>{let t=new FormData;return Object.entries(r).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(o=>U(t,e,o)):U(t,e,i));}),t}},C={bodySerializer:r=>JSON.stringify(r,(t,e)=>typeof e=="bigint"?e.toString():e)},N={bodySerializer:r=>{let t=new URLSearchParams;return Object.entries(r).forEach(([e,i])=>{i!=null&&(Array.isArray(i)?i.forEach(o=>k(t,e,o)):k(t,e,i));}),t.toString()}},I=r=>{switch(r){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},Q=r=>{switch(r){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},V=r=>{switch(r){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},S=({allowReserved:r,explode:t,name:e,style:i,value:o})=>{if(!t){let a=(r?o:o.map(u=>encodeURIComponent(u))).join(Q(i));switch(i){case "label":return `.${a}`;case "matrix":return `;${e}=${a}`;case "simple":return a;default:return `${e}=${a}`}}let n=I(i),s=o.map(a=>i==="label"||i==="simple"?r?a:encodeURIComponent(a):p({allowReserved:r,name:e,value:a})).join(n);return i==="label"||i==="matrix"?n+s:s},p=({allowReserved:r,name:t,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 `${t}=${r?e:encodeURIComponent(e)}`},z=({allowReserved:r,explode:t,name:e,style:i,value:o})=>{if(o instanceof Date)return `${e}=${o.toISOString()}`;if(i!=="deepObject"&&!t){let a=[];Object.entries(o).forEach(([l,d])=>{a=[...a,l,r?d:encodeURIComponent(d)];});let u=a.join(",");switch(i){case "form":return `${e}=${u}`;case "label":return `.${u}`;case "matrix":return `;${e}=${u}`;default:return u}}let n=V(i),s=Object.entries(o).map(([a,u])=>p({allowReserved:r,name:i==="deepObject"?`${e}[${a}]`:a,value:u})).join(n);return i==="label"||i==="matrix"?n+s:s};var W=/\{[^{}]+\}/g,J=({path:r,url:t})=>{let e=t,i=t.match(W);if(i)for(let o of i){let n=false,s=o.substring(1,o.length-1),a="simple";s.endsWith("*")&&(n=true,s=s.substring(0,s.length-1)),s.startsWith(".")?(s=s.substring(1),a="label"):s.startsWith(";")&&(s=s.substring(1),a="matrix");let u=vue.toValue(vue.toValue(r)[s]);if(u==null)continue;if(Array.isArray(u)){e=e.replace(o,S({explode:n,name:s,style:a,value:u}));continue}if(typeof u=="object"){e=e.replace(o,z({explode:n,name:s,style:a,value:u}));continue}if(a==="matrix"){e=e.replace(o,`;${p({name:s,value:u})}`);continue}let l=encodeURIComponent(a==="label"?`.${u}`:u);e=e.replace(o,l);}return e},v=({allowReserved:r,array:t,object:e}={})=>o=>{let n=[],s=vue.toValue(o);if(s&&typeof s=="object")for(let a in s){let u=vue.toValue(s[a]);if(u!=null){if(Array.isArray(u)){n=[...n,S({allowReserved:r,explode:true,name:a,style:"form",value:u,...t})];continue}if(typeof u=="object"){n=[...n,z({allowReserved:r,explode:true,name:a,style:"deepObject",value:u,...e})];continue}n=[...n,p({allowReserved:r,name:a,value:u})];}}return n.join("&")},B=async({security:r,...t})=>{for(let e of r){let i=await E(e,t.auth);if(!i)continue;let o=e.name??"Authorization";switch(e.in){case "query":t.query||(t.query={}),vue.toValue(t.query)[o]=i;break;case "header":default:t.headers.set(o,i);break}return}},h=r=>M({baseUrl:r.baseURL,path:r.path,query:r.query,querySerializer:typeof r.querySerializer=="function"?r.querySerializer:v(r.querySerializer),url:r.url}),M=({baseUrl:r,path:t,query:e,querySerializer:i,url:o})=>{let n=o.startsWith("/")?o:`/${o}`,s=(r??"")+n;t&&(s=J({path:t,url:s}));let a=e?i(e):"";return a.startsWith("?")&&(a=a.substring(1)),a&&(s+=`?${a}`),s},A=(r,t)=>{let e={...r,...t};return e.baseURL?.endsWith("/")&&(e.baseURL=e.baseURL.substring(0,e.baseURL.length-1)),e.headers=O(r.headers,t.headers),e},O=(...r)=>{let t=new Headers;for(let e of r){if(!e||typeof e!="object")continue;let i=e;vue.isRef(i)&&(i=vue.unref(i));let o=i instanceof Headers?i.entries():Object.entries(i);for(let[n,s]of o)if(s===null)t.delete(n);else if(Array.isArray(s))for(let a of s)t.append(n,y(a));else if(s!==undefined){let a=y(s);t.set(n,typeof a=="object"?JSON.stringify(a):a);}}return t},w=(...r)=>r.reduce((t,e)=>{if(typeof e=="function")t.push(e);else if(Array.isArray(e))return t.concat(e);return t},[]),_=v({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),K={"Content-Type":"application/json"},q=(r={})=>({...C,headers:K,querySerializer:_,...r}),y=r=>{if(r===null||typeof r!="object"||r instanceof Headers)return vue.isRef(r)?vue.unref(r):r;if(Array.isArray(r))return r.map(e=>y(e));if(vue.isRef(r))return y(vue.unref(r));let t={};for(let e in r)t[e]=y(r[e]);return t},b=r=>r.body&&r.bodySerializer?r.bodySerializer(r.body):r.body,P=(r,t)=>{let e=y(r);return e.body=b(e),t(h(r),e)};var re=(r={})=>{let t=A(q(),r),e=()=>({...t}),i=n=>(t=A(t,n),e()),o=({asyncDataOptions:n,composable:s,key:a,...u})=>{let l={...t,...u,$fetch:u.$fetch??t.$fetch??$fetch,headers:O(t.headers,u.headers),onRequest:w(t.onRequest,u.onRequest),onResponse:w(t.onResponse,u.onResponse)},{responseTransformer:d,responseValidator:R,security:j}=l;j&&(l.onRequest=[async({options:c})=>{await B({auth:l.auth,headers:c.headers,query:c.query,security:j});},...l.onRequest]),(d||R)&&(l.onResponse=[...l.onResponse,async({options:c,response:f})=>{c.responseType&&c.responseType!=="json"||f.ok&&(R&&await R(f._data),d&&(f._data=await d(f._data)));}]),l.body||l.headers.delete("Content-Type");let $=l.$fetch;if(s==="$fetch")return P(l,$);if(s==="useFetch"||s==="useLazyFetch"){let c=vue.reactive({body:l.body,bodySerializer:l.bodySerializer}),f=vue.ref(b(l));return l.body=f,vue.watch(c,D=>{f.value=b(D);}),s==="useLazyFetch"?app.useLazyFetch(()=>h(l),l):app.useFetch(()=>h(l),l)}let g=()=>P(l,$);if(s==="useAsyncData")return a?app.useAsyncData(a,g,n):app.useAsyncData(g,n);if(s==="useLazyAsyncData")return a?app.useLazyAsyncData(a,g,n):app.useLazyAsyncData(g,n)};return {buildUrl:h,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"}),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=re;exports.createConfig=q;exports.formDataBodySerializer=F;exports.jsonBodySerializer=C;exports.urlSearchParamsBodySerializer=N;//# sourceMappingURL=index.cjs.map | |||
'use strict';var app=require('nuxt/app'),vue=require('vue');var v=async(e,t)=>{let r=typeof t=="function"?await t(e):t;if(r)return e.scheme==="bearer"?`Bearer ${r}`:e.scheme==="basic"?`Basic ${btoa(r)}`:r},k=(e,t,r)=>{typeof r=="string"?e.append(t,r):e.append(t,JSON.stringify(r));},C=(e,t,r)=>{if(t!=null){if(typeof t=="string"||t instanceof Blob)return e.append(r??"key",t);if(typeof t!="object")return e.append(r??"key",JSON.stringify(t));if(Array.isArray(t)){t.forEach((s,a)=>{C(e,s,r?`${r}[${a}]`:`array[${a}]`);});return}for(let[s,a]of Object.entries(t))C(e,a,r?`${r}[${s}]`:s);}},F={bodySerializer:e=>{let t=new FormData;return C(t,e),t}},S={bodySerializer:e=>JSON.stringify(e,(t,r)=>typeof r=="bigint"?r.toString():r)},N={bodySerializer:e=>{let t=new URLSearchParams;return Object.entries(e).forEach(([r,s])=>{s!=null&&(Array.isArray(s)?s.forEach(a=>k(t,r,a)):k(t,r,s));}),t.toString()}},I=e=>{switch(e){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},Q=e=>{switch(e){case "form":return ",";case "pipeDelimited":return "|";case "spaceDelimited":return "%20";default:return ","}},V=e=>{switch(e){case "label":return ".";case "matrix":return ";";case "simple":return ",";default:return "&"}},z=({allowReserved:e,explode:t,name:r,style:s,value:a})=>{if(!t){let i=(e?a:a.map(u=>encodeURIComponent(u))).join(Q(s));switch(s){case "label":return `.${i}`;case "matrix":return `;${r}=${i}`;case "simple":return i;default:return `${r}=${i}`}}let n=I(s),o=a.map(i=>s==="label"||s==="simple"?e?i:encodeURIComponent(i):p({allowReserved:e,name:r,value:i})).join(n);return s==="label"||s==="matrix"?n+o:o},p=({allowReserved:e,name:t,value:r})=>{if(r==null)return "";if(typeof r=="object")throw new Error("Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these.");return `${t}=${e?r:encodeURIComponent(r)}`},x=({allowReserved:e,explode:t,name:r,style:s,value:a})=>{if(a instanceof Date)return `${r}=${a.toISOString()}`;if(s!=="deepObject"&&!t){let i=[];Object.entries(a).forEach(([l,d])=>{i=[...i,l,e?d:encodeURIComponent(d)];});let u=i.join(",");switch(s){case "form":return `${r}=${u}`;case "label":return `.${u}`;case "matrix":return `;${r}=${u}`;default:return u}}let n=V(s),o=Object.entries(a).map(([i,u])=>p({allowReserved:e,name:s==="deepObject"?`${r}[${i}]`:i,value:u})).join(n);return s==="label"||s==="matrix"?n+o:o};var W=/\{[^{}]+\}/g,J=({path:e,url:t})=>{let r=t,s=t.match(W);if(s)for(let a of s){let n=false,o=a.substring(1,a.length-1),i="simple";o.endsWith("*")&&(n=true,o=o.substring(0,o.length-1)),o.startsWith(".")?(o=o.substring(1),i="label"):o.startsWith(";")&&(o=o.substring(1),i="matrix");let u=vue.toValue(vue.toValue(e)[o]);if(u==null)continue;if(Array.isArray(u)){r=r.replace(a,z({explode:n,name:o,style:i,value:u}));continue}if(typeof u=="object"){r=r.replace(a,x({explode:n,name:o,style:i,value:u}));continue}if(i==="matrix"){r=r.replace(a,`;${p({name:o,value:u})}`);continue}let l=encodeURIComponent(i==="label"?`.${u}`:u);r=r.replace(a,l);}return r},E=({allowReserved:e,array:t,object:r}={})=>a=>{let n=[],o=vue.toValue(a);if(o&&typeof o=="object")for(let i in o){let u=vue.toValue(o[i]);if(u!=null){if(Array.isArray(u)){n=[...n,z({allowReserved:e,explode:true,name:i,style:"form",value:u,...t})];continue}if(typeof u=="object"){n=[...n,x({allowReserved:e,explode:true,name:i,style:"deepObject",value:u,...r})];continue}n=[...n,p({allowReserved:e,name:i,value:u})];}}return n.join("&")},B=async({security:e,...t})=>{for(let r of e){let s=await v(r,t.auth);if(!s)continue;let a=r.name??"Authorization";switch(r.in){case "query":t.query||(t.query={}),vue.toValue(t.query)[a]=s;break;case "header":default:t.headers.set(a,s);break}return}},h=e=>M({baseUrl:e.baseURL,path:e.path,query:e.query,querySerializer:typeof e.querySerializer=="function"?e.querySerializer:E(e.querySerializer),url:e.url}),M=({baseUrl:e,path:t,query:r,querySerializer:s,url:a})=>{let n=a.startsWith("/")?a:`/${a}`,o=(e??"")+n;t&&(o=J({path:t,url:o}));let i=r?s(r):"";return i.startsWith("?")&&(i=i.substring(1)),i&&(o+=`?${i}`),o},O=(e,t)=>{let r={...e,...t};return r.baseURL?.endsWith("/")&&(r.baseURL=r.baseURL.substring(0,r.baseURL.length-1)),r.headers=w(e.headers,t.headers),r},w=(...e)=>{let t=new Headers;for(let r of e){if(!r||typeof r!="object")continue;let s=r;vue.isRef(s)&&(s=vue.unref(s));let a=s instanceof Headers?s.entries():Object.entries(s);for(let[n,o]of a)if(o===null)t.delete(n);else if(Array.isArray(o))for(let i of o)t.append(n,y(i));else if(o!==undefined){let i=y(o);t.set(n,typeof i=="object"?JSON.stringify(i):i);}}return t},q=(...e)=>e.reduce((t,r)=>{if(typeof r=="function")t.push(r);else if(Array.isArray(r))return t.concat(r);return t},[]),_=E({allowReserved:false,array:{explode:true,style:"form"},object:{explode:true,style:"deepObject"}}),K={"Content-Type":"application/json"},P=(e={})=>({...S,headers:K,querySerializer:_,...e}),y=e=>{if(e===null||typeof e!="object"||e instanceof Headers)return vue.isRef(e)?vue.unref(e):e;if(Array.isArray(e))return e.map(r=>y(r));if(vue.isRef(e))return y(vue.unref(e));let t={};for(let r in e)t[r]=y(e[r]);return t},g=e=>e.body&&e.bodySerializer?e.bodySerializer(e.body):e.body,$=(e,t)=>{let r=y(e);return r.body=g(r),t(h(e),r)};var re=(e={})=>{let t=O(P(),e),r=()=>({...t}),s=n=>(t=O(t,n),r()),a=({asyncDataOptions:n,composable:o,key:i,...u})=>{let l={...t,...u,$fetch:u.$fetch??t.$fetch??$fetch,headers:w(t.headers,u.headers),onRequest:q(t.onRequest,u.onRequest),onResponse:q(t.onResponse,u.onResponse)},{responseTransformer:d,responseValidator:R,security:j}=l;j&&(l.onRequest=[async({options:c})=>{await B({auth:l.auth,headers:c.headers,query:c.query,security:j});},...l.onRequest]),(d||R)&&(l.onResponse=[...l.onResponse,async({options:c,response:f})=>{c.responseType&&c.responseType!=="json"||f.ok&&(R&&await R(f._data),d&&(f._data=await d(f._data)));}]),l.body||l.headers.delete("Content-Type");let U=l.$fetch;if(o==="$fetch")return $(l,U);if(o==="useFetch"||o==="useLazyFetch"){let c=vue.reactive({body:l.body,bodySerializer:l.bodySerializer}),f=vue.ref(g(l));return l.body=f,vue.watch(c,D=>{f.value=g(D);}),o==="useLazyFetch"?app.useLazyFetch(()=>h(l),l):app.useFetch(()=>h(l),l)}let b=()=>$(l,U);if(o==="useAsyncData")return i?app.useAsyncData(i,b,n):app.useAsyncData(b,n);if(o==="useLazyAsyncData")return i?app.useLazyAsyncData(i,b,n):app.useLazyAsyncData(b,n)};return {buildUrl:h,connect:n=>a({...n,method:"CONNECT"}),delete:n=>a({...n,method:"DELETE"}),get:n=>a({...n,method:"GET"}),getConfig:r,head:n=>a({...n,method:"HEAD"}),options:n=>a({...n,method:"OPTIONS"}),patch:n=>a({...n,method:"PATCH"}),post:n=>a({...n,method:"POST"}),put:n=>a({...n,method:"PUT"}),request:a,setConfig:s,trace:n=>a({...n,method:"TRACE"})}};exports.createClient=re;exports.createConfig=P;exports.formDataBodySerializer=F;exports.jsonBodySerializer=S;exports.urlSearchParamsBodySerializer=N;//# sourceMappingURL=index.cjs.map |
Check notice
Code scanning / CodeQL
Semicolon insertion Note test
the enclosing function
Copilot Autofix AI 17 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
Closes #1585