wretch
Version:
A tiny wrapper built around fetch with an intuitive syntax.
3 lines • 8.43 kB
JavaScript
(function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.wretch=t())})(this,function(){function e(e={}){let t=e instanceof Array?Object.fromEntries(e):e;for(let e in t)if(e.toLowerCase()===`content-type`)return t[e]}function t(e){return/^application\/.*json/.test(e)}let n=(e,t,r=!1)=>{let i={...e};for(let a in t){if(!Object.prototype.hasOwnProperty.call(t,a))continue;let o=e[a],s=t[a];i[a]=Array.isArray(o)&&Array.isArray(s)?r?[...o,...s]:s:typeof o==`object`&&typeof s==`object`?n(o,s,r):s}return i},r=Symbol(),i=Symbol(),a=e=>t=>e.reduceRight((e,t)=>t(e),t);var o=class extends Error{};let s=e=>{let t=Object.create(null);e=e._addons.reduce((n,r)=>r.beforeRequest&&r.beforeRequest(n,e._options,t)||n,e);let{_url:n,_options:s,_fetch:c,_errorTransformer:l,_catchers:u,_resolvers:d,_middlewares:f,_addons:p}=e,m=new Map(u),h=s,g=n,_=a(f)((e,t)=>(g=e,(c||fetch)(e,t)))(n,h),v=Error(),y=_.then(async e=>{if(!e.ok){let t=new o;if(t.cause=v,t.stack+=`
CAUSE: `+v.stack,t.response=e,t.status=e.status,t.url=g,e.type===`opaque`||l)t.message=e.statusText;else try{t.message=await e.clone().text()}catch{t.message=e.statusText}throw t}return e}),b=t=>t.catch(async t=>{let n=m.get(t?.status)||m.get(t?.name)||!(t instanceof o)&&m.get(r)||m.get(i);if(t.response&&l&&(t=await l(t,t.response,e)),n)return n(t,e);throw t}),x=e=>t=>{let n=e?y.then(t=>t?.[e]()):y;return b(t?n.then(t):n)},S={_wretchReq:e,_fetchReq:_,_sharedState:t,res:x(null),json:x(`json`),blob:x(`blob`),formData:x(`formData`),arrayBuffer:x(`arrayBuffer`),text:x(`text`),error(e,t){return m.set(e,t),this},badRequest(e){return this.error(400,e)},unauthorized(e){return this.error(401,e)},forbidden(e){return this.error(403,e)},notFound(e){return this.error(404,e)},timeout(e){return this.error(408,e)},internalError(e){return this.error(500,e)},fetchError(e){return this.error(r,e)}},C=p.reduce((e,t)=>({...e,...typeof t.resolver==`function`?t.resolver(e):t.resolver}),S);return d.reduce((t,n)=>n(t,e),C)},c={_url:``,_options:{},_catchers:new Map,_resolvers:[],_deferred:[],_middlewares:[],_addons:[],addon(e){let t=Array.isArray(e)?e:[e],n=t.reduce((e,t)=>({...e,...t.wretch}),{});return{...this,_addons:[...this._addons,...t],...n}},fetchPolyfill(e){return{...this,_fetch:e}},url(e,t=!1){if(t)return{...this,_url:e};let n=this._url.indexOf(`?`);return{...this,_url:n>-1?this._url.slice(0,n)+e+this._url.slice(n):this._url+e}},options(e,t=!1){return{...this,_options:t?e:n(this._options,e)}},headers(e){let t=e?Array.isArray(e)?Object.fromEntries(e):`entries`in e?Object.fromEntries(e.entries()):e:{};return{...this,_options:n(this._options,{headers:t})}},accept(e){return this.headers({Accept:e})},content(e){return this.headers({"Content-Type":e})},auth(e){return this.headers({Authorization:e})},catcher(e,t){let n=new Map(this._catchers),r=Array.isArray(e)?e:[e];for(let e of r)n.set(e,t);return{...this,_catchers:n}},catcherFallback(e){return this.catcher(i,e)},customError(e){return{...this,_errorTransformer:e}},resolve(e,t=!1){return{...this,_resolvers:t?[e]:[...this._resolvers,e]}},defer(e,t=!1){return{...this,_deferred:t?[e]:[...this._deferred,e]}},middlewares(e,t=!1){return{...this,_middlewares:t?e:[...this._middlewares,...e]}},fetch(n=this._options.method,r=``,i=null){let a=this.url(r).options({method:n}),o=e(a._options.headers),c=typeof i==`object`&&!(i instanceof FormData)&&(!a._options.headers||!o||t(o));return a=i?c?a.json(i,o):a.body(i):a,s(a._deferred.reduce((e,t)=>t(e,e._url,e._options),a))},get(e=``){return this.fetch(`GET`,e)},delete(e=``){return this.fetch(`DELETE`,e)},put(e,t=``){return this.fetch(`PUT`,t,e)},post(e,t=``){return this.fetch(`POST`,t,e)},patch(e,t=``){return this.fetch(`PATCH`,t,e)},head(e=``){return this.fetch(`HEAD`,e)},opts(e=``){return this.fetch(`OPTIONS`,e)},body(e){return{...this,_options:{...this._options,body:e}}},json(n,r){let i=e(this._options.headers);return this.content(r||t(i)&&i||`application/json`).body(JSON.stringify(n))},toFetch(){return(e,t={})=>this.url(e).options(t).catcherFallback(e=>{if(e instanceof o)return e.response;throw e}).fetch().res()}},l=()=>({beforeRequest(e,t,n){let r=new AbortController;t.signal||=r.signal;let i={ref:null,clear(){i.ref&&=(clearTimeout(i.ref),null)}};return n.abort={timeout:i,fetchController:r},e},wretch:{signal(e){return{...this,_options:{...this._options,signal:e.signal}}}},resolver:{setTimeout(e,t={}){let n=t.controller??this._sharedState.abort.fetchController,{timeout:r}=this._sharedState.abort;return r.clear(),r.ref=setTimeout(()=>n.abort(),e),this},controller(){return[this._sharedState.abort.fetchController,this]},onAbort(e){return this.error(`AbortError`,e)}}});function u(e){let t=new TextEncoder().encode(e);return btoa(String.fromCharCode(...t))}let d=()=>e=>(t,n)=>{let r;try{r=new URL(t)}catch{r=null}if(r?.username||r?.password){let e=u(`${decodeURIComponent(r.username)}:${decodeURIComponent(r.password)}`);n.headers={...n.headers,Authorization:`Basic ${e}`},r.username=``,r.password=``,t=r.toString()}return e(t,n)},f={beforeRequest(e){return e.middlewares([d()])},wretch:{basicAuth(e,t){let n=u(`${e}:${t}`);return this.auth(`Basic ${n}`)}}};function p(e,t=!1,n=new FormData,r=[]){return Object.entries(e).forEach(([e,i])=>{let a=r.reduce((e,t)=>e?`${e}[${t}]`:t,null);if(a=a?`${a}[${e}]`:e,i instanceof Array||globalThis.FileList&&i instanceof FileList)for(let e of i)n.append(a,e);else t&&typeof i==`object`&&(!(t instanceof Array)||!t.includes(e))?i!==null&&p(i,t,n,[...r,e]):n.append(a,i)}),n}let m={wretch:{formData(e,t={}){return this.body(p(e,t.recursive??!1))}}};function h(e,t){return encodeURIComponent(e)+`=`+encodeURIComponent(typeof t==`object`?JSON.stringify(t):``+t)}function g(e){return Object.keys(e).map(t=>{let n=e[t];return n instanceof Array?n.map(e=>h(t,e)).join(`&`):h(t,n)}).join(`&`)}let _={wretch:{formUrl(e){return this.body(typeof e==`string`?e:g(e)).content(`application/x-www-form-urlencoded`)}}},v=()=>{let e=new Map,t=null,n=(n,r,i,a)=>{if(!n.getEntriesByName)return!1;let o=n.getEntriesByName(r);return o&&o.length>0?(i(o.reverse()[0]),a.clearMeasures&&a.clearMeasures(r),e.delete(r),e.size<1&&(t.disconnect(),a.clearResourceTimings&&a.clearResourceTimings()),!0):!1},r=(r,i)=>(!t&&r&&i&&(t=new i(t=>{e.forEach((e,i)=>{n(t,i,e,r)})}),r.clearResourceTimings&&r.clearResourceTimings()),t),i=(i,a)=>{!i||!a||r(performance,PerformanceObserver)&&(n(performance,i,a,performance)||(e.size<1&&t.observe({entryTypes:[`resource`,`measure`]}),e.set(i,a)))};return{resolver:{perfs(e){return this._fetchReq.then(()=>i(this._wretchReq._url,e)).catch(()=>{}),this}}}},y=(e,t,n,r)=>{let i;if(typeof t==`string`)i=t;else{let e=new URLSearchParams;for(let n in t){let i=t[n];if(!(r&&i==null))if(Array.isArray(i))for(let t of i)e.append(n,t??``);else e.append(n,i??``)}i=e.toString()}let a=e.split(`?`);return i?n||a.length<2?a[0]+`?`+i:e+`&`+i:n?a[0]:e},b={wretch:{query(e,t={}){return{...this,_url:y(this._url,e,t.replace??!1,t.omitUndefinedOrNullValues??!1)}}}};function x(e,t,n){try{let r=e.headers.get(`content-length`),i=t||(r?+r:0),a=0,o=new TransformStream({start(){n?.(a,i)},transform(e,t){a+=e.length,i<a&&(i=a),n?.(a,i),t.enqueue(e)}}),s=e.body.pipeThrough(o);return`status`in e?new Response(s,e):new Request(e,{body:s,duplex:`half`})}catch{return e}}let S=async(e,t)=>{let n=t.body instanceof ArrayBuffer?+t.body.byteLength:t.body instanceof Blob?+t.body.size:0;try{n||=(await new Request(e,t).blob()).size}catch{}return n},C=({getUploadTotal:e=S}={})=>{function t(e){return t=>(n,r)=>t(n,r).then(t=>e.progress?x(t,0,e.progress):t)}function n(t){return n=>async(r,i)=>!i.body||!t.upload?n(r,i):n(r,x(new Request(r,i),await e(r,i),t.upload))}return{beforeRequest(e,r,i){let a=[];return r.__uploadProgressCallback&&(i.upload=r.__uploadProgressCallback,delete r.__uploadProgressCallback),r.__downloadProgressCallback&&(i.progress=r.__downloadProgressCallback,delete r.__downloadProgressCallback),a.push(n(i)),a.push(t(i)),e.middlewares(a)},wretch:{onUpload(e){return this.options({__uploadProgressCallback:e})},onDownload(e){return this.options({__downloadProgressCallback:e})}},resolver:{progress(e){return this._sharedState.progress=e,this}}}},w=(e=``,t={})=>({...c,_url:e,_options:t}).addon([l(),f,m,_,v(),b,C()]);return w.default=w,w.WretchError=o,w});
//# sourceMappingURL=wretch.all.min.js.map