@anmetric/neta 0.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -3
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/types/types.d.ts +1 -0
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
npm install neta
|
|
13
|
+
npm install @anmetric/neta
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Quick Start
|
|
@@ -296,6 +296,25 @@ await neta.post(url, {
|
|
|
296
296
|
});
|
|
297
297
|
```
|
|
298
298
|
|
|
299
|
+
##### bearerToken
|
|
300
|
+
|
|
301
|
+
Type: `string`
|
|
302
|
+
|
|
303
|
+
Convenience option to set the `Authorization: Bearer <token>` header. If an `Authorization` header is already set explicitly, `bearerToken` will not override it.
|
|
304
|
+
|
|
305
|
+
```js
|
|
306
|
+
const data = await neta.get('https://api.example.com/me', {
|
|
307
|
+
bearerToken: 'abc123',
|
|
308
|
+
}).json();
|
|
309
|
+
// Sets header: Authorization: Bearer abc123
|
|
310
|
+
|
|
311
|
+
// Works with create/extend
|
|
312
|
+
const api = neta.create({
|
|
313
|
+
prefix: 'https://api.example.com',
|
|
314
|
+
bearerToken: 'abc123',
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
299
318
|
##### context
|
|
300
319
|
|
|
301
320
|
Type: `Record<string, unknown>`\
|
|
@@ -393,7 +412,7 @@ Create a new instance with default options:
|
|
|
393
412
|
```js
|
|
394
413
|
const api = neta.create({
|
|
395
414
|
prefix: 'https://api.example.com',
|
|
396
|
-
|
|
415
|
+
bearerToken: 'my-token',
|
|
397
416
|
timeout: 30000,
|
|
398
417
|
retry: 3,
|
|
399
418
|
});
|
|
@@ -407,7 +426,7 @@ Alias for `neta.create()`. Creates a new instance by extending existing defaults
|
|
|
407
426
|
|
|
408
427
|
```js
|
|
409
428
|
const api = neta.create({ prefix: 'https://api.example.com' });
|
|
410
|
-
const authApi = api.extend({
|
|
429
|
+
const authApi = api.extend({ bearerToken: 'my-token' });
|
|
411
430
|
```
|
|
412
431
|
|
|
413
432
|
## Hooks
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var M=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var Re=(t,e)=>{for(var r in e)M(t,r,{get:e[r],enumerable:!0})},ge=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ye(e))!we.call(t,n)&&n!==r&&M(t,n,{get:()=>e[n],enumerable:!(o=pe(e,n))||o.enumerable});return t};var be=t=>ge(M({},"__esModule",{value:!0}),t);var Ue={};Re(Ue,{ForceRetryError:()=>k,HTTPError:()=>E,NetaClient:()=>z,NetaError:()=>E,NetworkError:()=>S,SchemaValidationError:()=>D,TimeoutError:()=>R,createInstance:()=>z,default:()=>Oe,neta:()=>fe,stop:()=>T});module.exports=be(Ue);var W=["get","post","put","patch","delete","head","options"],_={limit:2,methods:["get","put","head","delete","options"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:1/0,backoffLimit:1/0,delay:t=>300*2**(t-1),jitter:!1,retryOnTimeout:!1,shouldRetry:void 0},G=1e4,q=2147483647,K={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*",bytes:"*/*"},Fe=typeof globalThis.AbortController=="function",Me=typeof globalThis.AbortSignal<"u",_e=typeof globalThis.FormData=="function",Q=(()=>{try{return typeof globalThis.ReadableStream=="function"}catch{return!1}})(),X=(()=>{try{let t=!1,e=new Request(new URL("https://empty.invalid"),{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}catch{return!1}})();var E=class extends Error{constructor(e,r,o){let n=`${e.status}${e.statusText?` ${e.statusText}`:""}`;super(`Request failed with status code ${n}`),this.name="HTTPError",this.response=e,this.request=r,this.options=o,this.data=void 0}},R=class extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}},S=class extends Error{constructor(e,r){super("Network error",r),this.name="NetworkError",this.request=e}},k=class extends Error{constructor(e){super("Force retry"),this.name="ForceRetryError",this.customDelay=e?.delay,this.customRequest=e?.request}},D=class extends Error{constructor(e){let r=e.map(o=>o.message??"Unknown validation error").join("; ");super(`Schema validation failed: ${r}`),this.name="SchemaValidationError",this.issues=e}};var T=Symbol("neta.stop"),N=class{constructor(e){this.options=e}};function Z(t,e){let r=Number(t.headers.get("content-length"))||0,o=0,n=t.body.getReader(),i=new ReadableStream({async pull(p){let{done:y,value:d}=await n.read();if(y){e({percent:1,transferredBytes:o,totalBytes:r||o}),p.close();return}o+=d.byteLength;let g=r?o/r:0;e({percent:g,transferredBytes:o,totalBytes:r}),p.enqueue(d)},cancel(p){return n.cancel(p)}});return new Response(i,{status:t.status,statusText:t.statusText,headers:t.headers})}function ee(t,e,r){let o=Number(t.headers.get("content-length"))||0,n=0,i=t.body.getReader(),p=new ReadableStream({async pull(y){let{done:d,value:g}=await i.read();if(d){e({percent:1,transferredBytes:n,totalBytes:o||n}),y.close();return}n+=g.byteLength;let u=o?n/o:0;e({percent:u,transferredBytes:n,totalBytes:o}),y.enqueue(g)},cancel(y){return i.cancel(y)}});return new Request(t.url,{method:t.method,headers:t.headers,body:p,duplex:"half",signal:t.signal})}function xe(t){return typeof t=="number"?{..._,limit:t}:{..._,...t}}function Te(t){return{init:[...t?.init??[]],beforeRequest:[...t?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[]],beforeError:[...t?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[]]}}function Ee(t,e){let r=new Headers(t);return e&&new Headers(e).forEach((n,i)=>{r.set(i,n)}),r}function Se(t,e){return{init:[...t?.init??[],...e?.init??[]],beforeRequest:[...t?.beforeRequest??[],...e?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[],...e?.afterResponse??[]],beforeError:[...t?.beforeError??[],...e?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[],...e?.beforeRetry??[]]}}function $(t,e){if(!t)return e??{};if(!e)return t;let r={...t,...e};return(t.headers||e.headers)&&(r.headers=Ee(t.headers,e.headers)),(t.hooks||e.hooks)&&(r.hooks=Se(t.hooks,e.hooks)),r}function te(t,e){let r=t instanceof Request?t.url:String(t);if(e?.prefix){let o=String(e.prefix).replace(/\/+$/,""),n=r.replace(/^\/+/,"");r=`${o}/${n}`}if(e?.baseUrl)try{new URL(r)}catch{r=new URL(r,new Request(String(e.baseUrl)).url).href}return r}function re(t,e){if(!e)return t;if(typeof e=="string"){let o=e.replace(/^\?/,"");return o&&(t.search=t.search?`${t.search}&${o}`:`?${o}`),t}let r;if(e instanceof URLSearchParams)r=e;else if(Array.isArray(e))r=new URLSearchParams(e);else{r=new URLSearchParams;for(let[o,n]of Object.entries(e))n!==void 0&&r.set(o,String(n))}return r.forEach((o,n)=>{t.searchParams.append(n,o)}),t}function ne(t){let e={...t,method:ke(t.method??"get"),retry:xe(t.retry),timeout:t.timeout??G,totalTimeout:t.totalTimeout??!1,hooks:Te(t.hooks),throwHttpErrors:t.throwHttpErrors??!0,fetch:t.fetch??globalThis.fetch.bind(globalThis),context:t.context??{},prefix:t.prefix?String(t.prefix):""};if(t.json!==void 0){e.body=e.stringifyJson?e.stringifyJson(t.json):JSON.stringify(t.json);let r=new Headers(e.headers);r.has("content-type")||r.set("content-type","application/json"),e.headers=r}return e}function ke(t){return(t??"get").toLowerCase()}function v(t,e){return new Promise((r,o)=>{let n=e?.signal;if(n?.aborted){o(n.reason??new DOMException("Aborted","AbortError"));return}let i=setTimeout(r,t);n&&n.addEventListener("abort",()=>{clearTimeout(i),o(n.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function oe(t){let e=t.headers.get("retry-after")??t.headers.get("ratelimit-reset")??t.headers.get("x-ratelimit-retry-after")??t.headers.get("x-ratelimit-reset")??t.headers.get("x-rate-limit-reset");if(!e)return;let r=Number(e);if(!Number.isNaN(r))return r>=Date.parse("2024-01-01")/1e3?Math.max(0,r*1e3-Date.now()):r*1e3;let o=Date.parse(e);if(!Number.isNaN(o))return Math.max(0,o-Date.now())}function se(t,e){if(e===!0)return Math.random()*t;if(typeof e=="function"){let r=e(t);return Number.isFinite(r)&&r>=0?r:t}return t}function ae(t){return t instanceof TypeError&&(t.message==="Failed to fetch"||t.message==="fetch failed"||t.message==="NetworkError when attempting to fetch resource."||t.message.includes("network")||t.message.includes("ECONNREFUSED")||t.message.includes("ENOTFOUND")||t.message.includes("ETIMEDOUT")||t.message.includes("ECONNRESET"))}var ie="The `schema` argument must follow the Standard Schema specification";async function ce(t,e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError(ie);let r=e["~standard"];if(typeof r!="object"||r===null||typeof r.validate!="function")throw new TypeError(ie);let o=await r.validate(t);if(o.issues)throw new D(o.issues);return o.value}function qe(t,e){let r=new AbortController,o;return t!==!1&&typeof t=="number"&&(o=setTimeout(()=>r.abort("timeout"),t)),e&&(e.aborted?r.abort(e.reason):e.addEventListener("abort",()=>r.abort(e.reason),{once:!0})),{signal:r.signal,cleanup:()=>{o&&clearTimeout(o)}}}async function De(t,e){let{body:r}=t;if(!r)try{return await t.text()}catch{return}let o;try{o=r.getReader()}catch{return}let n=new TextDecoder,i=[],p=0,y=10*1024*1024,d=(async()=>{try{for(;;){let{done:b,value:w}=await o.read();if(b)break;if(p+=w.byteLength,p>y){o.cancel().catch(()=>{});return}i.push(n.decode(w,{stream:!0}))}}catch{return}return i.push(n.decode()),i.join("")})(),g=new Promise(b=>{let w=setTimeout(()=>b(void 0),e);d.finally(()=>clearTimeout(w))}),u=await Promise.race([d,g]);return u===void 0&&o.cancel().catch(()=>{}),u}async function Ne(t,e,r,o){let n=await De(t,e);if(!n)return;let i=(t.headers.get("content-type")??"").split(";",1)[0].trim().toLowerCase();if(!/\/(?:.*[.+-])?json$/.test(i))return n;try{return r.parseJson?await r.parseJson(n,{request:o,response:t}):JSON.parse(n)}catch{return}}function A(t){let{hooks:e,json:r,parseJson:o,stringifyJson:n,searchParams:i,timeout:p,totalTimeout:y,throwHttpErrors:d,fetch:g,context:u,_userSignal:b,prefix:w,baseUrl:U,onDownloadProgress:c,onUploadProgress:J,...I}=t;return Object.freeze(I)}function O(t,e){let r=t.delay(e),o=se(r,t.jitter);return Math.min(t.backoffLimit,o)}function ue(t,e){for(let u of e.hooks.init)u(e);let r=0,o=typeof e.totalTimeout=="number"?performance.now():void 0,n,i=()=>{if(o===void 0)return;let u=performance.now()-o;return Math.max(0,e.totalTimeout-u)},p=()=>{let u=i();return e.timeout===!1?u:u===void 0?e.timeout:Math.min(e.timeout,u)},y=()=>{let u=i();if(u!==void 0&&u<=0)throw new R(n)},d=(async()=>{if(typeof e.timeout=="number"&&e.timeout>q)throw new RangeError(`The \`timeout\` option cannot be greater than ${q}`);if(typeof e.totalTimeout=="number"&&e.totalTimeout>q)throw new RangeError(`The \`totalTimeout\` option cannot be greater than ${q}`);let u=te(t,{prefix:e.prefix,baseUrl:e.baseUrl}),b=new URL(u);b=re(b,e.searchParams);let{prefix:w,baseUrl:U,retry:c,timeout:J,totalTimeout:I,hooks:H,searchParams:Ae,json:Je,throwHttpErrors:P,fetch:le,parseJson:He,stringifyJson:Pe,context:Ce,_userSignal:Le,onDownloadProgress:C,onUploadProgress:B,...de}=e;n=new Request(b.href,{...de,method:e.method.toUpperCase()}),await Promise.resolve();for(let a of H.beforeRequest){let s=await a({request:n,options:A(e),retryCount:0});if(s instanceof Response)return s;s instanceof Request&&(n=s)}let V=e._userSignal,Y=async()=>{let a=p(),s=i();if(s!==void 0&&s<=0)throw new R(n);let l=qe(a,V),f=n.clone();B&&f.body&&X&&(f=ee(f,B,e.body));try{let h=await le(f,{signal:l.signal});return l.cleanup(),h}catch(h){throw l.cleanup(),l.signal.aborted&&l.signal.reason==="timeout"?new R(n):ae(h)?new S(n,{cause:h}):h}},L=async(a,s)=>{let l=Math.min(s,q),f={signal:V},h=i();if(h!==void 0){if(h<=0)throw new R(n);if(l>=h)throw await v(h,f),new R(n)}await v(l,f),y();for(let F of H.beforeRetry){let x=await F({request:n,options:A(e),error:a,retryCount:r+1});if(x instanceof Request){n=x;break}if(x instanceof Response)return r++,x;if(x===T)return T}return y(),r++,Y()},me=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return O(c,r+1)}if(a instanceof R){if(!c.retryOnTimeout)throw a;return O(c,r+1)}if(a instanceof S)return O(c,r+1);throw a},he=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return O(c,r+1)}if(!c.statusCodes.includes(a.response.status))throw a;if(c.afterStatusCodes.includes(a.response.status)){let s=oe(a.response);if(s!==void 0)return Math.min(c.maxRetryAfter,Math.max(0,s))}if(a.response.status===413)throw a;return O(c,r+1)},m;for(;;)try{m=await Y();break}catch(a){let s=await me(a),l=await L(a,s);if(l===T)return;if(l instanceof Response){m=l;break}}let j=!1;for(;;){try{for(let s of H.afterResponse){let l=m.clone(),f=await s({request:n,options:A(e),response:l,retryCount:r});if(f instanceof N)throw new k(f.options);f instanceof Response&&(m=f)}}catch(s){if(!(s instanceof k))throw s;let l=s.customDelay??O(c,r+1);s.customRequest&&(n=s.customRequest);let f=await L(s,l);if(f===T)return;if(f instanceof Response){m=f,j=!0;continue}continue}let a=typeof P=="function"?P(m.status):P;if(!m.ok&&m.type!=="opaque"&&a){let s=new E(m,n,A(e));if(s.data=await Ne(m,e.timeout===!1?1e4:e.timeout,e,n),j)throw s;let l;try{l=await he(s)}catch{let h=s;for(let F of H.beforeError){let x=await F({request:n,options:A(e),error:h,retryCount:r});x instanceof Error&&(h=x)}throw h}let f=await L(s,l);if(f===T)return;if(f instanceof Response){m=f,j=!1;continue}continue}break}if(e.parseJson&&(m.json=async()=>{let a=await m.clone().text();return a===""?JSON.parse(a):e.parseJson(a,{request:n,response:m})}),C){if(typeof C!="function")throw new TypeError("The `onDownloadProgress` option must be a function");if(!Q)throw new Error("Streams are not supported. `ReadableStream` is missing.");return Z(m,C)}return m})(),g={then:d.then.bind(d),catch:d.catch.bind(d),finally:d.finally.bind(d),[Symbol.toStringTag]:"ResponsePromise"};for(let[u,b]of Object.entries(K))g[u]=async w=>{n&&n.headers.set("accept",n.headers.get("accept")||b);let U=await d;if(u!=="json")return U[u]();let c=await U.text();if(c==="")return w!==void 0?ce(void 0,w):JSON.parse(c);let J=e.parseJson?await e.parseJson(c,{request:n,response:U}):JSON.parse(c);return w===void 0?J:ce(J,w)};return g}function z(t){let e=(r,o)=>{let n=$(t,o),i=ne(n);return i._userSignal=i.signal??void 0,ue(r,i)};for(let r of W)e[r]=(o,n)=>e(o,{...n,method:r});return e.create=r=>z($(t,r)),e.extend=e.create,e.retry=r=>new N(r),e}var fe=z(),Oe=fe;0&&(module.exports={ForceRetryError,HTTPError,NetaClient,NetaError,NetworkError,SchemaValidationError,TimeoutError,createInstance,neta,stop});
|
|
1
|
+
"use strict";var _=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var be=(t,e)=>{for(var r in e)_(t,r,{get:e[r],enumerable:!0})},Re=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ye(e))!we.call(t,n)&&n!==r&&_(t,n,{get:()=>e[n],enumerable:!(o=pe(e,n))||o.enumerable});return t};var ge=t=>Re(_({},"__esModule",{value:!0}),t);var Ue={};be(Ue,{ForceRetryError:()=>k,HTTPError:()=>E,NetaClient:()=>z,NetaError:()=>E,NetworkError:()=>S,SchemaValidationError:()=>N,TimeoutError:()=>b,createInstance:()=>z,default:()=>Oe,neta:()=>ue,stop:()=>T});module.exports=ge(Ue);var Y=["get","post","put","patch","delete","head","options"],M={limit:2,methods:["get","put","head","delete","options"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:1/0,backoffLimit:1/0,delay:t=>300*2**(t-1),jitter:!1,retryOnTimeout:!1,shouldRetry:void 0},W=1e4,D=2147483647,G={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*",bytes:"*/*"},_e=typeof globalThis.AbortController=="function",Me=typeof globalThis.AbortSignal<"u",$e=typeof globalThis.FormData=="function",K=(()=>{try{return typeof globalThis.ReadableStream=="function"}catch{return!1}})(),Q=(()=>{try{let t=!1,e=new Request(new URL("https://empty.invalid"),{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}catch{return!1}})();var E=class extends Error{constructor(e,r,o){let n=`${e.status}${e.statusText?` ${e.statusText}`:""}`;super(`Request failed with status code ${n}`),this.name="HTTPError",this.response=e,this.request=r,this.options=o,this.data=void 0}},b=class extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}},S=class extends Error{constructor(e,r){super("Network error",r),this.name="NetworkError",this.request=e}},k=class extends Error{constructor(e){super("Force retry"),this.name="ForceRetryError",this.customDelay=e?.delay,this.customRequest=e?.request}},N=class extends Error{constructor(e){let r=e.map(o=>o.message??"Unknown validation error").join("; ");super(`Schema validation failed: ${r}`),this.name="SchemaValidationError",this.issues=e}};var T=Symbol("neta.stop"),O=class{constructor(e){this.options=e}};function X(t,e){let r=Number(t.headers.get("content-length"))||0,o=0,n=t.body.getReader(),i=new ReadableStream({async pull(p){let{done:y,value:l}=await n.read();if(y){e({percent:1,transferredBytes:o,totalBytes:r||o}),p.close();return}o+=l.byteLength;let R=r?o/r:0;e({percent:R,transferredBytes:o,totalBytes:r}),p.enqueue(l)},cancel(p){return n.cancel(p)}});return new Response(i,{status:t.status,statusText:t.statusText,headers:t.headers})}function Z(t,e,r){let o=Number(t.headers.get("content-length"))||0,n=0,i=t.body.getReader(),p=new ReadableStream({async pull(y){let{done:l,value:R}=await i.read();if(l){e({percent:1,transferredBytes:n,totalBytes:o||n}),y.close();return}n+=R.byteLength;let u=o?n/o:0;e({percent:u,transferredBytes:n,totalBytes:o}),y.enqueue(R)},cancel(y){return i.cancel(y)}});return new Request(t.url,{method:t.method,headers:t.headers,body:p,duplex:"half",signal:t.signal})}function xe(t){return typeof t=="number"?{...M,limit:t}:{...M,...t}}function Te(t){return{init:[...t?.init??[]],beforeRequest:[...t?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[]],beforeError:[...t?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[]]}}function Ee(t,e){let r=new Headers(t);return e&&new Headers(e).forEach((n,i)=>{r.set(i,n)}),r}function Se(t,e){return{init:[...t?.init??[],...e?.init??[]],beforeRequest:[...t?.beforeRequest??[],...e?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[],...e?.afterResponse??[]],beforeError:[...t?.beforeError??[],...e?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[],...e?.beforeRetry??[]]}}function $(t,e){if(!t)return e??{};if(!e)return t;let r={...t,...e};return(t.headers||e.headers)&&(r.headers=Ee(t.headers,e.headers)),(t.hooks||e.hooks)&&(r.hooks=Se(t.hooks,e.hooks)),r}function ee(t,e){let r=t instanceof Request?t.url:String(t);if(e?.prefix){let o=String(e.prefix).replace(/\/+$/,""),n=r.replace(/^\/+/,"");r=`${o}/${n}`}if(e?.baseUrl)try{new URL(r)}catch{r=new URL(r,new Request(String(e.baseUrl)).url).href}return r}function te(t,e){if(!e)return t;if(typeof e=="string"){let o=e.replace(/^\?/,"");return o&&(t.search=t.search?`${t.search}&${o}`:`?${o}`),t}let r;if(e instanceof URLSearchParams)r=e;else if(Array.isArray(e))r=new URLSearchParams(e);else{r=new URLSearchParams;for(let[o,n]of Object.entries(e))n!==void 0&&r.set(o,String(n))}return r.forEach((o,n)=>{t.searchParams.append(n,o)}),t}function re(t){let e={...t,method:ke(t.method??"get"),retry:xe(t.retry),timeout:t.timeout??W,totalTimeout:t.totalTimeout??!1,hooks:Te(t.hooks),throwHttpErrors:t.throwHttpErrors??!0,fetch:t.fetch??globalThis.fetch.bind(globalThis),context:t.context??{},prefix:t.prefix?String(t.prefix):""};if(t.bearerToken!==void 0){let r=new Headers(e.headers);r.has("authorization")||r.set("authorization",`Bearer ${t.bearerToken}`),e.headers=r}if(t.json!==void 0){e.body=e.stringifyJson?e.stringifyJson(t.json):JSON.stringify(t.json);let r=new Headers(e.headers);r.has("content-type")||r.set("content-type","application/json"),e.headers=r}return e}function ke(t){return(t??"get").toLowerCase()}function v(t,e){return new Promise((r,o)=>{let n=e?.signal;if(n?.aborted){o(n.reason??new DOMException("Aborted","AbortError"));return}let i=setTimeout(r,t);n&&n.addEventListener("abort",()=>{clearTimeout(i),o(n.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function ne(t){let e=t.headers.get("retry-after")??t.headers.get("ratelimit-reset")??t.headers.get("x-ratelimit-retry-after")??t.headers.get("x-ratelimit-reset")??t.headers.get("x-rate-limit-reset");if(!e)return;let r=Number(e);if(!Number.isNaN(r))return r>=Date.parse("2024-01-01")/1e3?Math.max(0,r*1e3-Date.now()):r*1e3;let o=Date.parse(e);if(!Number.isNaN(o))return Math.max(0,o-Date.now())}function oe(t,e){if(e===!0)return Math.random()*t;if(typeof e=="function"){let r=e(t);return Number.isFinite(r)&&r>=0?r:t}return t}function se(t){return t instanceof TypeError&&(t.message==="Failed to fetch"||t.message==="fetch failed"||t.message==="NetworkError when attempting to fetch resource."||t.message.includes("network")||t.message.includes("ECONNREFUSED")||t.message.includes("ENOTFOUND")||t.message.includes("ETIMEDOUT")||t.message.includes("ECONNRESET"))}var ae="The `schema` argument must follow the Standard Schema specification";async function ie(t,e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError(ae);let r=e["~standard"];if(typeof r!="object"||r===null||typeof r.validate!="function")throw new TypeError(ae);let o=await r.validate(t);if(o.issues)throw new N(o.issues);return o.value}function qe(t,e){let r=new AbortController,o;return t!==!1&&typeof t=="number"&&(o=setTimeout(()=>r.abort("timeout"),t)),e&&(e.aborted?r.abort(e.reason):e.addEventListener("abort",()=>r.abort(e.reason),{once:!0})),{signal:r.signal,cleanup:()=>{o&&clearTimeout(o)}}}async function De(t,e){let{body:r}=t;if(!r)try{return await t.text()}catch{return}let o;try{o=r.getReader()}catch{return}let n=new TextDecoder,i=[],p=0,y=10*1024*1024,l=(async()=>{try{for(;;){let{done:g,value:w}=await o.read();if(g)break;if(p+=w.byteLength,p>y){o.cancel().catch(()=>{});return}i.push(n.decode(w,{stream:!0}))}}catch{return}return i.push(n.decode()),i.join("")})(),R=new Promise(g=>{let w=setTimeout(()=>g(void 0),e);l.finally(()=>clearTimeout(w))}),u=await Promise.race([l,R]);return u===void 0&&o.cancel().catch(()=>{}),u}async function Ne(t,e,r,o){let n=await De(t,e);if(!n)return;let i=(t.headers.get("content-type")??"").split(";",1)[0].trim().toLowerCase();if(!/\/(?:.*[.+-])?json$/.test(i))return n;try{return r.parseJson?await r.parseJson(n,{request:o,response:t}):JSON.parse(n)}catch{return}}function H(t){let{hooks:e,json:r,parseJson:o,stringifyJson:n,searchParams:i,timeout:p,totalTimeout:y,throwHttpErrors:l,fetch:R,context:u,_userSignal:g,prefix:w,baseUrl:A,onDownloadProgress:c,onUploadProgress:J,bearerToken:fe,...q}=t;return Object.freeze(q)}function U(t,e){let r=t.delay(e),o=oe(r,t.jitter);return Math.min(t.backoffLimit,o)}function ce(t,e){for(let u of e.hooks.init)u(e);let r=0,o=typeof e.totalTimeout=="number"?performance.now():void 0,n,i=()=>{if(o===void 0)return;let u=performance.now()-o;return Math.max(0,e.totalTimeout-u)},p=()=>{let u=i();return e.timeout===!1?u:u===void 0?e.timeout:Math.min(e.timeout,u)},y=()=>{let u=i();if(u!==void 0&&u<=0)throw new b(n)},l=(async()=>{if(typeof e.timeout=="number"&&e.timeout>D)throw new RangeError(`The \`timeout\` option cannot be greater than ${D}`);if(typeof e.totalTimeout=="number"&&e.totalTimeout>D)throw new RangeError(`The \`totalTimeout\` option cannot be greater than ${D}`);let u=ee(t,{prefix:e.prefix,baseUrl:e.baseUrl}),g=new URL(u);g=te(g,e.searchParams);let{prefix:w,baseUrl:A,retry:c,timeout:J,totalTimeout:fe,hooks:q,searchParams:Ae,json:He,throwHttpErrors:P,fetch:de,parseJson:Je,stringifyJson:Pe,context:Ce,_userSignal:Le,onDownloadProgress:C,onUploadProgress:B,bearerToken:je,...le}=e;n=new Request(g.href,{...le,method:e.method.toUpperCase()}),await Promise.resolve();for(let a of q.beforeRequest){let s=await a({request:n,options:H(e),retryCount:0});if(s instanceof Response)return s;s instanceof Request&&(n=s)}let I=e._userSignal,V=async()=>{let a=p(),s=i();if(s!==void 0&&s<=0)throw new b(n);let d=qe(a,I),f=n.clone();B&&f.body&&Q&&(f=Z(f,B,e.body));try{let h=await de(f,{signal:d.signal});return d.cleanup(),h}catch(h){throw d.cleanup(),d.signal.aborted&&d.signal.reason==="timeout"?new b(n):se(h)?new S(n,{cause:h}):h}},L=async(a,s)=>{let d=Math.min(s,D),f={signal:I},h=i();if(h!==void 0){if(h<=0)throw new b(n);if(d>=h)throw await v(h,f),new b(n)}await v(d,f),y();for(let F of q.beforeRetry){let x=await F({request:n,options:H(e),error:a,retryCount:r+1});if(x instanceof Request){n=x;break}if(x instanceof Response)return r++,x;if(x===T)return T}return y(),r++,V()},me=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return U(c,r+1)}if(a instanceof b){if(!c.retryOnTimeout)throw a;return U(c,r+1)}if(a instanceof S)return U(c,r+1);throw a},he=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return U(c,r+1)}if(!c.statusCodes.includes(a.response.status))throw a;if(c.afterStatusCodes.includes(a.response.status)){let s=ne(a.response);if(s!==void 0)return Math.min(c.maxRetryAfter,Math.max(0,s))}if(a.response.status===413)throw a;return U(c,r+1)},m;for(;;)try{m=await V();break}catch(a){let s=await me(a),d=await L(a,s);if(d===T)return;if(d instanceof Response){m=d;break}}let j=!1;for(;;){try{for(let s of q.afterResponse){let d=m.clone(),f=await s({request:n,options:H(e),response:d,retryCount:r});if(f instanceof O)throw new k(f.options);f instanceof Response&&(m=f)}}catch(s){if(!(s instanceof k))throw s;let d=s.customDelay??U(c,r+1);s.customRequest&&(n=s.customRequest);let f=await L(s,d);if(f===T)return;if(f instanceof Response){m=f,j=!0;continue}continue}let a=typeof P=="function"?P(m.status):P;if(!m.ok&&m.type!=="opaque"&&a){let s=new E(m,n,H(e));if(s.data=await Ne(m,e.timeout===!1?1e4:e.timeout,e,n),j)throw s;let d;try{d=await he(s)}catch{let h=s;for(let F of q.beforeError){let x=await F({request:n,options:H(e),error:h,retryCount:r});x instanceof Error&&(h=x)}throw h}let f=await L(s,d);if(f===T)return;if(f instanceof Response){m=f,j=!1;continue}continue}break}if(e.parseJson&&(m.json=async()=>{let a=await m.clone().text();return a===""?JSON.parse(a):e.parseJson(a,{request:n,response:m})}),C){if(typeof C!="function")throw new TypeError("The `onDownloadProgress` option must be a function");if(!K)throw new Error("Streams are not supported. `ReadableStream` is missing.");return X(m,C)}return m})(),R={then:l.then.bind(l),catch:l.catch.bind(l),finally:l.finally.bind(l),[Symbol.toStringTag]:"ResponsePromise"};for(let[u,g]of Object.entries(G))R[u]=async w=>{n&&n.headers.set("accept",n.headers.get("accept")||g);let A=await l;if(u!=="json")return A[u]();let c=await A.text();if(c==="")return w!==void 0?ie(void 0,w):JSON.parse(c);let J=e.parseJson?await e.parseJson(c,{request:n,response:A}):JSON.parse(c);return w===void 0?J:ie(J,w)};return R}function z(t){let e=(r,o)=>{let n=$(t,o),i=re(n);return i._userSignal=i.signal??void 0,ce(r,i)};for(let r of Y)e[r]=(o,n)=>e(o,{...n,method:r});return e.create=r=>z($(t,r)),e.extend=e.create,e.retry=r=>new O(r),e}var ue=z(),Oe=ue;0&&(module.exports={ForceRetryError,HTTPError,NetaClient,NetaError,NetworkError,SchemaValidationError,TimeoutError,createInstance,neta,stop});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js","../src/constants.js","../src/errors.js","../src/types.js","../src/stream.js","../src/utils.js","../src/core.js"],"sourcesContent":["import { HTTP_METHODS } from './constants.js';\nimport { createResponsePromise } from './core.js';\nimport { RetryMarker } from './types.js';\nimport { mergeOptions, normalizeOptions } from './utils.js';\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @returns {import('../types/types.js').NetaInstance}\n */\nexport function createInstance(defaults) {\n const fn = (input, options) => {\n const merged = mergeOptions(defaults, options);\n const normalized = normalizeOptions(merged);\n // Stash user signal before we override it internally\n normalized._userSignal = normalized.signal ?? undefined;\n return createResponsePromise(input, normalized);\n };\n\n for (const method of HTTP_METHODS) {\n fn[method] = (input, options) => fn(input, { ...options, method });\n }\n\n fn.create = (newDefaults) => createInstance(mergeOptions(defaults, newDefaults));\n fn.extend = fn.create;\n\n /**\n * Signal forced retry from an afterResponse hook.\n * @param {{ delay?: number, request?: Request }} [options]\n * @returns {RetryMarker}\n */\n fn.retry = (options) => new RetryMarker(options);\n\n return fn;\n}\n\nconst neta = createInstance();\n\nexport default neta;\nexport { neta };\nexport { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nexport { HTTPError as NetaError } from './errors.js';\nexport { createInstance as NetaClient };\nexport { stop } from './types.js';\n","/** @type {import('../types/types.js').HttpMethod[]} */\nexport const HTTP_METHODS = [\n 'get', 'post', 'put', 'patch', 'delete', 'head', 'options',\n];\n\n/** @type {import('../types/types.js').RetryOptions} */\nexport const DEFAULT_RETRY = {\n limit: 2,\n methods: ['get', 'put', 'head', 'delete', 'options'],\n statusCodes: [408, 413, 429, 500, 502, 503, 504],\n afterStatusCodes: [413, 429, 503],\n maxRetryAfter: Infinity,\n backoffLimit: Infinity,\n delay: (attemptCount) => 300 * 2 ** (attemptCount - 1),\n jitter: false,\n retryOnTimeout: false,\n shouldRetry: undefined,\n};\n\nexport const DEFAULT_TIMEOUT = 10_000;\n\nexport const maxSafeTimeout = 2_147_483_647; // 2^31 - 1\n\n/** @type {Record<string, string>} */\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n bytes: '*/*',\n};\n\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal !== 'undefined';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\n\nexport const supportsResponseStreams = (() => {\n try {\n return typeof globalThis.ReadableStream === 'function';\n } catch {\n return false;\n }\n})();\n\nexport const supportsRequestStreams = (() => {\n try {\n let duplexAccessed = false;\n const hasContentType = new Request(\n new URL('https://empty.invalid'),\n {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n },\n ).headers.has('Content-Type');\n return duplexAccessed && !hasContentType;\n } catch {\n return false;\n }\n})();\n","export class HTTPError extends Error {\n /**\n * @param {Response} response\n * @param {Request} request\n * @param {import('./types.js').NormalizedOptions} options\n */\n constructor(response, request, options) {\n const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ''}`;\n super(`Request failed with status code ${status}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n /** @type {unknown} */\n this.data = undefined;\n }\n}\n\nexport class TimeoutError extends Error {\n /**\n * @param {Request} request\n */\n constructor(request) {\n super('Request timed out');\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n\nexport class NetworkError extends Error {\n /**\n * @param {Request} request\n * @param {{ cause?: Error }} [options]\n */\n constructor(request, options) {\n super('Network error', options);\n this.name = 'NetworkError';\n this.request = request;\n }\n}\n\nexport class ForceRetryError extends Error {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n super('Force retry');\n this.name = 'ForceRetryError';\n this.customDelay = options?.delay;\n this.customRequest = options?.request;\n }\n}\n\nexport class SchemaValidationError extends Error {\n /**\n * @param {Array<{ message?: string, path?: Array<string | number | symbol> }>} issues\n */\n constructor(issues) {\n const message = issues.map((i) => i.message ?? 'Unknown validation error').join('; ');\n super(`Schema validation failed: ${message}`);\n this.name = 'SchemaValidationError';\n this.issues = issues;\n }\n}\n","/** @type {unique symbol} */\nexport const stop = Symbol('neta.stop');\n\nexport class RetryMarker {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n this.options = options;\n }\n}\n","/**\n * @param {Response} response\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onDownloadProgress\n * @returns {Response}\n */\nexport function streamResponse(response, onDownloadProgress) {\n const totalBytes = Number(response.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = response.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onDownloadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onDownloadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n}\n\n/**\n * @param {Request} request\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onUploadProgress\n * @param {BodyInit} [originalBody]\n * @returns {Request}\n */\nexport function streamRequest(request, onUploadProgress, originalBody) {\n const totalBytes = Number(request.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = request.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onUploadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onUploadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n duplex: 'half',\n signal: request.signal,\n });\n}\n","import { DEFAULT_RETRY, DEFAULT_TIMEOUT } from './constants.js';\n\n/**\n * @param {import('../types/types.js').Options['retry']} retry\n * @returns {import('../types/types.js').RetryOptions}\n */\nexport function normalizeRetry(retry) {\n if (typeof retry === 'number') {\n return { ...DEFAULT_RETRY, limit: retry };\n }\n return { ...DEFAULT_RETRY, ...retry };\n}\n\n/**\n * @param {import('../types/types.js').Hooks} [hooks]\n * @returns {import('../types/types.js').NormalizedHooks}\n */\nexport function normalizeHooks(hooks) {\n return {\n init: [...(hooks?.init ?? [])],\n beforeRequest: [...(hooks?.beforeRequest ?? [])],\n afterResponse: [...(hooks?.afterResponse ?? [])],\n beforeError: [...(hooks?.beforeError ?? [])],\n beforeRetry: [...(hooks?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {HeadersInit} [target]\n * @param {HeadersInit} [source]\n * @returns {Headers}\n */\nexport function mergeHeaders(target, source) {\n const result = new Headers(target);\n if (source) {\n const sourceHeaders = new Headers(source);\n sourceHeaders.forEach((value, key) => {\n result.set(key, value);\n });\n }\n return result;\n}\n\n/**\n * Merge hooks by concatenating arrays.\n * @param {import('../types/types.js').Hooks} [base]\n * @param {import('../types/types.js').Hooks} [override]\n * @returns {import('../types/types.js').Hooks}\n */\nexport function mergeHooks(base, override) {\n return {\n init: [...(base?.init ?? []), ...(override?.init ?? [])],\n beforeRequest: [...(base?.beforeRequest ?? []), ...(override?.beforeRequest ?? [])],\n afterResponse: [...(base?.afterResponse ?? []), ...(override?.afterResponse ?? [])],\n beforeError: [...(base?.beforeError ?? []), ...(override?.beforeError ?? [])],\n beforeRetry: [...(base?.beforeRetry ?? []), ...(override?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @param {import('../types/types.js').Options} [overrides]\n * @returns {import('../types/types.js').Options}\n */\nexport function mergeOptions(defaults, overrides) {\n if (!defaults) return overrides ?? {};\n if (!overrides) return defaults;\n\n const merged = { ...defaults, ...overrides };\n\n if (defaults.headers || overrides.headers) {\n merged.headers = mergeHeaders(defaults.headers, overrides.headers);\n }\n\n if (defaults.hooks || overrides.hooks) {\n merged.hooks = mergeHooks(defaults.hooks, overrides.hooks);\n }\n\n return merged;\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {{ prefix?: string, baseUrl?: string | URL }} [options]\n * @returns {string}\n */\nexport function resolveInput(input, options) {\n let inputStr = input instanceof Request ? input.url : String(input);\n\n if (options?.prefix) {\n const prefix = String(options.prefix).replace(/\\/+$/, '');\n const path = inputStr.replace(/^\\/+/, '');\n inputStr = `${prefix}/${path}`;\n }\n\n if (options?.baseUrl) {\n try {\n // If already absolute, keep as-is\n new URL(inputStr);\n } catch {\n // Relative — resolve against baseUrl\n inputStr = new URL(inputStr, new Request(String(options.baseUrl)).url).href;\n }\n }\n\n return inputStr;\n}\n\n/**\n * @param {URL} url\n * @param {import('../types/types.js').SearchParamsInit} [searchParams]\n * @returns {URL}\n */\nexport function appendSearchParams(url, searchParams) {\n if (!searchParams) return url;\n\n if (typeof searchParams === 'string') {\n const cleaned = searchParams.replace(/^\\?/, '');\n if (cleaned) {\n url.search = url.search ? `${url.search}&${cleaned}` : `?${cleaned}`;\n }\n return url;\n }\n\n /** @type {URLSearchParams} */\n let params;\n\n if (searchParams instanceof URLSearchParams) {\n params = searchParams;\n } else if (Array.isArray(searchParams)) {\n params = new URLSearchParams(searchParams);\n } else {\n params = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n }\n\n params.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n return url;\n}\n\n/**\n * @param {import('../types/types.js').Options} options\n * @returns {import('../types/types.js').InternalOptions}\n */\nexport function normalizeOptions(options) {\n const normalized = {\n ...options,\n method: normalizeRequestMethod(options.method ?? 'get'),\n retry: normalizeRetry(options.retry),\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n totalTimeout: options.totalTimeout ?? false,\n hooks: normalizeHooks(options.hooks),\n throwHttpErrors: options.throwHttpErrors ?? true,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n prefix: options.prefix ? String(options.prefix) : '',\n };\n\n if (options.json !== undefined) {\n normalized.body = normalized.stringifyJson\n ? normalized.stringifyJson(options.json)\n : JSON.stringify(options.json);\n const headers = new Headers(normalized.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n normalized.headers = headers;\n }\n\n return normalized;\n}\n\n/**\n * @param {string} [method]\n * @returns {string}\n */\nexport function normalizeRequestMethod(method) {\n return (method ?? 'get').toLowerCase();\n}\n\n/**\n * @param {number} ms\n * @param {{ signal?: AbortSignal }} [options]\n * @returns {Promise<void>}\n */\nexport function delay(ms, options) {\n return new Promise((resolve, reject) => {\n const signal = options?.signal;\n\n if (signal?.aborted) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timer = setTimeout(resolve, ms);\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n }\n });\n}\n\n/**\n * Parse Retry-After from multiple common header formats.\n * @param {Response} response\n * @returns {number | undefined}\n */\nexport function parseRetryAfter(response) {\n const header =\n response.headers.get('retry-after') ??\n response.headers.get('ratelimit-reset') ??\n response.headers.get('x-ratelimit-retry-after') ??\n response.headers.get('x-ratelimit-reset') ??\n response.headers.get('x-rate-limit-reset');\n\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) {\n // Large numbers are treated as timestamps (threshold: 2024-01-01 epoch)\n if (seconds >= Date.parse('2024-01-01') / 1000) {\n return Math.max(0, seconds * 1000 - Date.now());\n }\n return seconds * 1000;\n }\n\n const date = Date.parse(header);\n if (!Number.isNaN(date)) {\n return Math.max(0, date - Date.now());\n }\n\n return undefined;\n}\n\n/**\n * Apply jitter to a delay value.\n * @param {number} delayMs\n * @param {boolean | ((delay: number) => number)} jitter\n * @returns {number}\n */\nexport function applyJitter(delayMs, jitter) {\n if (jitter === true) {\n return Math.random() * delayMs;\n }\n if (typeof jitter === 'function') {\n const result = jitter(delayMs);\n return Number.isFinite(result) && result >= 0 ? result : delayMs;\n }\n return delayMs;\n}\n\n/**\n * Check if error is a raw network error (TypeError from fetch).\n * @param {unknown} error\n * @returns {boolean}\n */\nexport function isNetworkError(error) {\n return (\n error instanceof TypeError &&\n (error.message === 'Failed to fetch' ||\n error.message === 'fetch failed' ||\n error.message === 'NetworkError when attempting to fetch resource.' ||\n error.message.includes('network') ||\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('ENOTFOUND') ||\n error.message.includes('ETIMEDOUT') ||\n error.message.includes('ECONNRESET'))\n );\n}\n","import { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nimport { RetryMarker } from './types.js';\nimport { stop } from './types.js';\nimport { streamResponse, streamRequest } from './stream.js';\nimport {\n appendSearchParams,\n resolveInput,\n delay,\n isNetworkError,\n applyJitter,\n parseRetryAfter,\n} from './utils.js';\nimport {\n maxSafeTimeout,\n responseTypes,\n supportsResponseStreams,\n supportsRequestStreams,\n} from './constants.js';\n\nconst invalidSchemaMessage = 'The `schema` argument must follow the Standard Schema specification';\n\n/**\n * @param {unknown} jsonValue\n * @param {any} schema\n * @returns {Promise<unknown>}\n */\nasync function validateJsonWithSchema(jsonValue, schema) {\n if ((typeof schema !== 'object' && typeof schema !== 'function') || schema === null) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const standardSchema = schema['~standard'];\n if (\n typeof standardSchema !== 'object' ||\n standardSchema === null ||\n typeof standardSchema.validate !== 'function'\n ) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const result = await standardSchema.validate(jsonValue);\n if (result.issues) {\n throw new SchemaValidationError(result.issues);\n }\n\n return result.value;\n}\n\n/**\n * @param {number | false} timeout\n * @param {AbortSignal} [userSignal]\n * @returns {{ signal: AbortSignal, cleanup: () => void }}\n */\nfunction createManagedSignal(timeout, userSignal) {\n const controller = new AbortController();\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let timer;\n\n if (timeout !== false && typeof timeout === 'number') {\n timer = setTimeout(() => controller.abort('timeout'), timeout);\n }\n\n if (userSignal) {\n if (userSignal.aborted) {\n controller.abort(userSignal.reason);\n } else {\n userSignal.addEventListener('abort', () => controller.abort(userSignal.reason), { once: true });\n }\n }\n\n return {\n signal: controller.signal,\n cleanup: () => {\n if (timer) clearTimeout(timer);\n },\n };\n}\n\n/**\n * Read response text with timeout and size limit.\n * @param {Response} response\n * @param {number} timeoutMs\n * @returns {Promise<string | undefined>}\n */\nasync function readResponseText(response, timeoutMs) {\n const { body } = response;\n if (!body) {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n }\n\n /** @type {ReadableStreamDefaultReader<Uint8Array>} */\n let reader;\n try {\n reader = body.getReader();\n } catch {\n return undefined;\n }\n\n const decoder = new TextDecoder();\n const chunks = [];\n let totalBytes = 0;\n const maxSize = 10 * 1024 * 1024;\n\n const readAll = (async () => {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n totalBytes += value.byteLength;\n if (totalBytes > maxSize) {\n void reader.cancel().catch(() => {});\n return undefined;\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n } catch {\n return undefined;\n }\n chunks.push(decoder.decode());\n return chunks.join('');\n })();\n\n const timeoutPromise = new Promise((resolve) => {\n const id = setTimeout(() => resolve(undefined), timeoutMs);\n void readAll.finally(() => clearTimeout(id));\n });\n\n const result = await Promise.race([readAll, timeoutPromise]);\n if (result === undefined) void reader.cancel().catch(() => {});\n return result;\n}\n\n/**\n * @param {Response} response\n * @param {number} timeoutMs\n * @param {any} options\n * @param {Request} request\n * @returns {Promise<unknown>}\n */\nasync function getResponseData(response, timeoutMs, options, request) {\n const text = await readResponseText(response, timeoutMs);\n if (!text) return undefined;\n\n const contentType = (response.headers.get('content-type') ?? '').split(';', 1)[0].trim().toLowerCase();\n const isJson = /\\/(?:.*[.+-])?json$/.test(contentType);\n if (!isJson) return text;\n\n try {\n return options.parseJson\n ? await options.parseJson(text, { request, response })\n : JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Strip internal-only options.\n * @param {any} options\n * @returns {any}\n */\nfunction getNormalizedOptions(options) {\n const {\n hooks, json, parseJson, stringifyJson, searchParams,\n timeout, totalTimeout, throwHttpErrors, fetch,\n context, _userSignal, prefix, baseUrl,\n onDownloadProgress, onUploadProgress,\n ...rest\n } = options;\n return Object.freeze(rest);\n}\n\n/**\n * Calculate retry delay.\n * @param {any} retry\n * @param {number} retryCount\n * @returns {number}\n */\nfunction calculateDelay(retry, retryCount) {\n const base = retry.delay(retryCount);\n const jittered = applyJitter(base, retry.jitter);\n return Math.min(retry.backoffLimit, jittered);\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {any} options\n * @returns {any}\n */\nexport function createResponsePromise(input, options) {\n // Run init hooks (synchronous, mutate options clone)\n for (const hook of options.hooks.init) {\n hook(options);\n }\n\n let retryCount = 0;\n const startTime = typeof options.totalTimeout === 'number' ? performance.now() : undefined;\n /** @type {Request} */\n let currentRequest;\n\n const getRemainingTotalTimeout = () => {\n if (startTime === undefined) return undefined;\n const elapsed = performance.now() - startTime;\n return Math.max(0, options.totalTimeout - elapsed);\n };\n\n const getEffectiveTimeout = () => {\n const remaining = getRemainingTotalTimeout();\n if (options.timeout === false) return remaining;\n if (remaining === undefined) return options.timeout;\n return Math.min(options.timeout, remaining);\n };\n\n const throwIfTotalTimeoutExhausted = () => {\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) {\n throw new TimeoutError(currentRequest);\n }\n };\n\n const innerPromise = (async () => {\n if (typeof options.timeout === 'number' && options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n if (typeof options.totalTimeout === 'number' && options.totalTimeout > maxSafeTimeout) {\n throw new RangeError(`The \\`totalTimeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n\n // Resolve URL\n const inputStr = resolveInput(input, { prefix: options.prefix, baseUrl: options.baseUrl });\n let url = new URL(inputStr);\n url = appendSearchParams(url, options.searchParams);\n\n // Build request init (strip neta-specific options)\n const {\n prefix: _prefix, baseUrl: _baseUrl, retry, timeout, totalTimeout,\n hooks, searchParams, json, throwHttpErrors, fetch: fetchFn,\n parseJson, stringifyJson, context, _userSignal,\n onDownloadProgress, onUploadProgress,\n ...requestInit\n } = options;\n\n currentRequest = new Request(url.href, {\n ...requestInit,\n method: options.method.toUpperCase(),\n });\n\n // Defer so body shortcuts can set Accept header\n await Promise.resolve();\n\n // beforeRequest hooks\n for (const hook of hooks.beforeRequest) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n retryCount: 0,\n });\n\n if (result instanceof Response) return result;\n if (result instanceof Request) currentRequest = result;\n }\n\n const userSignal = options._userSignal;\n\n /**\n * Perform a single fetch attempt with timeout.\n * @returns {Promise<Response>}\n */\n const doFetch = async () => {\n const effectiveTimeout = getEffectiveTimeout();\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) throw new TimeoutError(currentRequest);\n\n const managed = createManagedSignal(effectiveTimeout, userSignal);\n\n let fetchRequest = currentRequest.clone();\n if (onUploadProgress && fetchRequest.body && supportsRequestStreams) {\n fetchRequest = streamRequest(fetchRequest, onUploadProgress, options.body);\n }\n\n try {\n const response = await fetchFn(fetchRequest, { signal: managed.signal });\n managed.cleanup();\n return response;\n } catch (error) {\n managed.cleanup();\n if (managed.signal.aborted && managed.signal.reason === 'timeout') {\n throw new TimeoutError(currentRequest);\n }\n if (isNetworkError(error)) {\n throw new NetworkError(currentRequest, { cause: error });\n }\n throw error;\n }\n };\n\n /**\n * Attempt retry: wait, run beforeRetry hooks, then fetch again.\n * @param {Error} error\n * @param {number} delayMs\n * @returns {Promise<Response | typeof stop>}\n */\n const attemptRetry = async (error, delayMs) => {\n const safeDelay = Math.min(delayMs, maxSafeTimeout);\n const delayOptions = { signal: userSignal };\n\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined) {\n if (remaining <= 0) throw new TimeoutError(currentRequest);\n if (safeDelay >= remaining) {\n await delay(remaining, delayOptions);\n throw new TimeoutError(currentRequest);\n }\n }\n\n await delay(safeDelay, delayOptions);\n throwIfTotalTimeoutExhausted();\n\n // Run beforeRetry hooks\n for (const hook of hooks.beforeRetry) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error,\n retryCount: retryCount + 1,\n });\n\n if (result instanceof Request) { currentRequest = result; break; }\n if (result instanceof Response) { retryCount++; return result; }\n if (result === stop) return stop;\n }\n\n throwIfTotalTimeoutExhausted();\n retryCount++;\n return doFetch();\n };\n\n /**\n * Check if we should retry a fetch-level error (timeout, network).\n * @param {Error} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForFetchError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof TimeoutError) {\n if (!retry.retryOnTimeout) throw error;\n return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof NetworkError) {\n return calculateDelay(retry, retryCount + 1);\n }\n\n throw error;\n };\n\n /**\n * Check if we should retry an HTTP error.\n * @param {HTTPError} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForHttpError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (!retry.statusCodes.includes(error.response.status)) throw error;\n\n // Handle Retry-After\n if (retry.afterStatusCodes.includes(error.response.status)) {\n const retryAfter = parseRetryAfter(error.response);\n if (retryAfter !== undefined) {\n return Math.min(retry.maxRetryAfter, Math.max(0, retryAfter));\n }\n }\n\n if (error.response.status === 413) throw error;\n\n return calculateDelay(retry, retryCount + 1);\n };\n\n // === Main request loop ===\n /** @type {Response} */\n let response;\n\n // Initial fetch with fetch-error retry loop\n for (;;) {\n try {\n response = await doFetch();\n break;\n } catch (error) {\n const retryDelay = await getRetryDelayForFetchError(error);\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) { response = retryResult; break; }\n }\n }\n\n // afterResponse hooks + HTTP error retry loop\n let responseFromHook = false;\n\n for (;;) {\n // Run afterResponse hooks\n try {\n for (const hook of hooks.afterResponse) {\n const clonedResponse = response.clone();\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n response: clonedResponse,\n retryCount,\n });\n\n if (hookResult instanceof RetryMarker) {\n throw new ForceRetryError(hookResult.options);\n }\n\n if (hookResult instanceof Response) {\n response = hookResult;\n }\n }\n } catch (error) {\n if (!(error instanceof ForceRetryError)) throw error;\n\n // Forced retry from afterResponse hook\n const retryDelay = error.customDelay ?? calculateDelay(retry, retryCount + 1);\n if (error.customRequest) currentRequest = error.customRequest;\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = true;\n continue;\n }\n continue;\n }\n\n // Check HTTP errors\n const shouldThrow = typeof throwHttpErrors === 'function'\n ? throwHttpErrors(response.status)\n : throwHttpErrors;\n\n if (!response.ok && response.type !== 'opaque' && shouldThrow) {\n const error = new HTTPError(response, currentRequest, getNormalizedOptions(options));\n error.data = await getResponseData(\n response,\n options.timeout === false ? 10_000 : options.timeout,\n options,\n currentRequest,\n );\n\n if (responseFromHook) throw error;\n\n // Try to retry\n let retryDelay;\n try {\n retryDelay = await getRetryDelayForHttpError(error);\n } catch {\n // Run beforeError hooks, then throw\n let processedError = error;\n for (const hook of hooks.beforeError) {\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error: processedError,\n retryCount,\n });\n if (hookResult instanceof Error) processedError = hookResult;\n }\n throw processedError;\n }\n\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = false; // Allow further retries\n continue;\n }\n continue;\n }\n\n break;\n }\n\n // Decorate response with custom parseJson\n if (options.parseJson) {\n response.json = async () => {\n const text = await response.clone().text();\n if (text === '') return JSON.parse(text);\n return options.parseJson(text, { request: currentRequest, response });\n };\n }\n\n // Handle download progress\n if (onDownloadProgress) {\n if (typeof onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported. `ReadableStream` is missing.');\n }\n return streamResponse(response, onDownloadProgress);\n }\n\n return response;\n })();\n\n // Build ResponsePromise thenable\n /** @type {any} */\n const responsePromise = {\n then: innerPromise.then.bind(innerPromise),\n catch: innerPromise.catch.bind(innerPromise),\n finally: innerPromise.finally.bind(innerPromise),\n [Symbol.toStringTag]: 'ResponsePromise',\n };\n\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n responsePromise[type] = async (schema) => {\n if (currentRequest) {\n currentRequest.headers.set('accept', currentRequest.headers.get('accept') || mimeType);\n }\n\n const response = await innerPromise;\n if (type !== 'json') return response[type]();\n\n const text = await response.text();\n if (text === '') {\n if (schema !== undefined) return validateJsonWithSchema(undefined, schema);\n return JSON.parse(text);\n }\n\n const jsonValue = options.parseJson\n ? await options.parseJson(text, { request: currentRequest, response })\n : JSON.parse(text);\n\n return schema === undefined ? jsonValue : validateJsonWithSchema(jsonValue, schema);\n };\n }\n\n return responsePromise;\n}\n"],"mappings":"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","names":["index_exports","__export","ForceRetryError","HTTPError","createInstance","NetworkError","SchemaValidationError","TimeoutError","index_default","neta","stop","__toCommonJS","HTTP_METHODS","DEFAULT_RETRY","attemptCount","DEFAULT_TIMEOUT","maxSafeTimeout","responseTypes","supportsAbortController","supportsAbortSignal","supportsFormData","supportsResponseStreams","supportsRequestStreams","duplexAccessed","hasContentType","HTTPError","response","request","options","status","TimeoutError","NetworkError","ForceRetryError","SchemaValidationError","issues","message","i","stop","RetryMarker","options","streamResponse","response","onDownloadProgress","totalBytes","transferredBytes","reader","stream","controller","done","value","percent","reason","streamRequest","request","onUploadProgress","originalBody","normalizeRetry","retry","DEFAULT_RETRY","normalizeHooks","hooks","mergeHeaders","target","source","result","value","key","mergeHooks","base","override","mergeOptions","defaults","overrides","merged","resolveInput","input","options","inputStr","prefix","path","appendSearchParams","url","searchParams","cleaned","params","normalizeOptions","normalized","normalizeRequestMethod","DEFAULT_TIMEOUT","headers","method","delay","ms","resolve","reject","signal","timer","parseRetryAfter","response","header","seconds","date","applyJitter","delayMs","jitter","isNetworkError","error","invalidSchemaMessage","validateJsonWithSchema","jsonValue","schema","standardSchema","result","SchemaValidationError","createManagedSignal","timeout","userSignal","controller","timer","readResponseText","response","timeoutMs","body","reader","decoder","chunks","totalBytes","maxSize","readAll","done","value","timeoutPromise","resolve","id","getResponseData","options","request","text","contentType","getNormalizedOptions","hooks","json","parseJson","stringifyJson","searchParams","totalTimeout","throwHttpErrors","fetch","context","_userSignal","prefix","baseUrl","onDownloadProgress","onUploadProgress","rest","calculateDelay","retry","retryCount","base","jittered","applyJitter","createResponsePromise","input","hook","startTime","currentRequest","getRemainingTotalTimeout","elapsed","getEffectiveTimeout","remaining","throwIfTotalTimeoutExhausted","TimeoutError","innerPromise","maxSafeTimeout","inputStr","resolveInput","url","appendSearchParams","_prefix","_baseUrl","fetchFn","requestInit","doFetch","effectiveTimeout","managed","fetchRequest","supportsRequestStreams","streamRequest","error","isNetworkError","NetworkError","attemptRetry","delayMs","safeDelay","delayOptions","delay","stop","getRetryDelayForFetchError","getRetryDelayForHttpError","retryAfter","parseRetryAfter","retryDelay","retryResult","responseFromHook","clonedResponse","hookResult","RetryMarker","ForceRetryError","shouldThrow","HTTPError","processedError","supportsResponseStreams","streamResponse","responsePromise","type","mimeType","responseTypes","createInstance","defaults","fn","input","options","merged","mergeOptions","normalized","normalizeOptions","createResponsePromise","method","HTTP_METHODS","newDefaults","RetryMarker","neta","index_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js","../src/constants.js","../src/errors.js","../src/types.js","../src/stream.js","../src/utils.js","../src/core.js"],"sourcesContent":["import { HTTP_METHODS } from './constants.js';\nimport { createResponsePromise } from './core.js';\nimport { RetryMarker } from './types.js';\nimport { mergeOptions, normalizeOptions } from './utils.js';\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @returns {import('../types/types.js').NetaInstance}\n */\nexport function createInstance(defaults) {\n const fn = (input, options) => {\n const merged = mergeOptions(defaults, options);\n const normalized = normalizeOptions(merged);\n // Stash user signal before we override it internally\n normalized._userSignal = normalized.signal ?? undefined;\n return createResponsePromise(input, normalized);\n };\n\n for (const method of HTTP_METHODS) {\n fn[method] = (input, options) => fn(input, { ...options, method });\n }\n\n fn.create = (newDefaults) => createInstance(mergeOptions(defaults, newDefaults));\n fn.extend = fn.create;\n\n /**\n * Signal forced retry from an afterResponse hook.\n * @param {{ delay?: number, request?: Request }} [options]\n * @returns {RetryMarker}\n */\n fn.retry = (options) => new RetryMarker(options);\n\n return fn;\n}\n\nconst neta = createInstance();\n\nexport default neta;\nexport { neta };\nexport { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nexport { HTTPError as NetaError } from './errors.js';\nexport { createInstance as NetaClient };\nexport { stop } from './types.js';\n","/** @type {import('../types/types.js').HttpMethod[]} */\nexport const HTTP_METHODS = [\n 'get', 'post', 'put', 'patch', 'delete', 'head', 'options',\n];\n\n/** @type {import('../types/types.js').RetryOptions} */\nexport const DEFAULT_RETRY = {\n limit: 2,\n methods: ['get', 'put', 'head', 'delete', 'options'],\n statusCodes: [408, 413, 429, 500, 502, 503, 504],\n afterStatusCodes: [413, 429, 503],\n maxRetryAfter: Infinity,\n backoffLimit: Infinity,\n delay: (attemptCount) => 300 * 2 ** (attemptCount - 1),\n jitter: false,\n retryOnTimeout: false,\n shouldRetry: undefined,\n};\n\nexport const DEFAULT_TIMEOUT = 10_000;\n\nexport const maxSafeTimeout = 2_147_483_647; // 2^31 - 1\n\n/** @type {Record<string, string>} */\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n bytes: '*/*',\n};\n\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal !== 'undefined';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\n\nexport const supportsResponseStreams = (() => {\n try {\n return typeof globalThis.ReadableStream === 'function';\n } catch {\n return false;\n }\n})();\n\nexport const supportsRequestStreams = (() => {\n try {\n let duplexAccessed = false;\n const hasContentType = new Request(\n new URL('https://empty.invalid'),\n {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n },\n ).headers.has('Content-Type');\n return duplexAccessed && !hasContentType;\n } catch {\n return false;\n }\n})();\n","export class HTTPError extends Error {\n /**\n * @param {Response} response\n * @param {Request} request\n * @param {import('./types.js').NormalizedOptions} options\n */\n constructor(response, request, options) {\n const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ''}`;\n super(`Request failed with status code ${status}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n /** @type {unknown} */\n this.data = undefined;\n }\n}\n\nexport class TimeoutError extends Error {\n /**\n * @param {Request} request\n */\n constructor(request) {\n super('Request timed out');\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n\nexport class NetworkError extends Error {\n /**\n * @param {Request} request\n * @param {{ cause?: Error }} [options]\n */\n constructor(request, options) {\n super('Network error', options);\n this.name = 'NetworkError';\n this.request = request;\n }\n}\n\nexport class ForceRetryError extends Error {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n super('Force retry');\n this.name = 'ForceRetryError';\n this.customDelay = options?.delay;\n this.customRequest = options?.request;\n }\n}\n\nexport class SchemaValidationError extends Error {\n /**\n * @param {Array<{ message?: string, path?: Array<string | number | symbol> }>} issues\n */\n constructor(issues) {\n const message = issues.map((i) => i.message ?? 'Unknown validation error').join('; ');\n super(`Schema validation failed: ${message}`);\n this.name = 'SchemaValidationError';\n this.issues = issues;\n }\n}\n","/** @type {unique symbol} */\nexport const stop = Symbol('neta.stop');\n\nexport class RetryMarker {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n this.options = options;\n }\n}\n","/**\n * @param {Response} response\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onDownloadProgress\n * @returns {Response}\n */\nexport function streamResponse(response, onDownloadProgress) {\n const totalBytes = Number(response.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = response.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onDownloadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onDownloadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n}\n\n/**\n * @param {Request} request\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onUploadProgress\n * @param {BodyInit} [originalBody]\n * @returns {Request}\n */\nexport function streamRequest(request, onUploadProgress, originalBody) {\n const totalBytes = Number(request.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = request.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onUploadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onUploadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n duplex: 'half',\n signal: request.signal,\n });\n}\n","import { DEFAULT_RETRY, DEFAULT_TIMEOUT } from './constants.js';\n\n/**\n * @param {import('../types/types.js').Options['retry']} retry\n * @returns {import('../types/types.js').RetryOptions}\n */\nexport function normalizeRetry(retry) {\n if (typeof retry === 'number') {\n return { ...DEFAULT_RETRY, limit: retry };\n }\n return { ...DEFAULT_RETRY, ...retry };\n}\n\n/**\n * @param {import('../types/types.js').Hooks} [hooks]\n * @returns {import('../types/types.js').NormalizedHooks}\n */\nexport function normalizeHooks(hooks) {\n return {\n init: [...(hooks?.init ?? [])],\n beforeRequest: [...(hooks?.beforeRequest ?? [])],\n afterResponse: [...(hooks?.afterResponse ?? [])],\n beforeError: [...(hooks?.beforeError ?? [])],\n beforeRetry: [...(hooks?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {HeadersInit} [target]\n * @param {HeadersInit} [source]\n * @returns {Headers}\n */\nexport function mergeHeaders(target, source) {\n const result = new Headers(target);\n if (source) {\n const sourceHeaders = new Headers(source);\n sourceHeaders.forEach((value, key) => {\n result.set(key, value);\n });\n }\n return result;\n}\n\n/**\n * Merge hooks by concatenating arrays.\n * @param {import('../types/types.js').Hooks} [base]\n * @param {import('../types/types.js').Hooks} [override]\n * @returns {import('../types/types.js').Hooks}\n */\nexport function mergeHooks(base, override) {\n return {\n init: [...(base?.init ?? []), ...(override?.init ?? [])],\n beforeRequest: [...(base?.beforeRequest ?? []), ...(override?.beforeRequest ?? [])],\n afterResponse: [...(base?.afterResponse ?? []), ...(override?.afterResponse ?? [])],\n beforeError: [...(base?.beforeError ?? []), ...(override?.beforeError ?? [])],\n beforeRetry: [...(base?.beforeRetry ?? []), ...(override?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @param {import('../types/types.js').Options} [overrides]\n * @returns {import('../types/types.js').Options}\n */\nexport function mergeOptions(defaults, overrides) {\n if (!defaults) return overrides ?? {};\n if (!overrides) return defaults;\n\n const merged = { ...defaults, ...overrides };\n\n if (defaults.headers || overrides.headers) {\n merged.headers = mergeHeaders(defaults.headers, overrides.headers);\n }\n\n if (defaults.hooks || overrides.hooks) {\n merged.hooks = mergeHooks(defaults.hooks, overrides.hooks);\n }\n\n return merged;\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {{ prefix?: string, baseUrl?: string | URL }} [options]\n * @returns {string}\n */\nexport function resolveInput(input, options) {\n let inputStr = input instanceof Request ? input.url : String(input);\n\n if (options?.prefix) {\n const prefix = String(options.prefix).replace(/\\/+$/, '');\n const path = inputStr.replace(/^\\/+/, '');\n inputStr = `${prefix}/${path}`;\n }\n\n if (options?.baseUrl) {\n try {\n // If already absolute, keep as-is\n new URL(inputStr);\n } catch {\n // Relative — resolve against baseUrl\n inputStr = new URL(inputStr, new Request(String(options.baseUrl)).url).href;\n }\n }\n\n return inputStr;\n}\n\n/**\n * @param {URL} url\n * @param {import('../types/types.js').SearchParamsInit} [searchParams]\n * @returns {URL}\n */\nexport function appendSearchParams(url, searchParams) {\n if (!searchParams) return url;\n\n if (typeof searchParams === 'string') {\n const cleaned = searchParams.replace(/^\\?/, '');\n if (cleaned) {\n url.search = url.search ? `${url.search}&${cleaned}` : `?${cleaned}`;\n }\n return url;\n }\n\n /** @type {URLSearchParams} */\n let params;\n\n if (searchParams instanceof URLSearchParams) {\n params = searchParams;\n } else if (Array.isArray(searchParams)) {\n params = new URLSearchParams(searchParams);\n } else {\n params = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n }\n\n params.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n return url;\n}\n\n/**\n * @param {import('../types/types.js').Options} options\n * @returns {import('../types/types.js').InternalOptions}\n */\nexport function normalizeOptions(options) {\n const normalized = {\n ...options,\n method: normalizeRequestMethod(options.method ?? 'get'),\n retry: normalizeRetry(options.retry),\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n totalTimeout: options.totalTimeout ?? false,\n hooks: normalizeHooks(options.hooks),\n throwHttpErrors: options.throwHttpErrors ?? true,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n prefix: options.prefix ? String(options.prefix) : '',\n };\n\n if (options.bearerToken !== undefined) {\n const headers = new Headers(normalized.headers);\n if (!headers.has('authorization')) {\n headers.set('authorization', `Bearer ${options.bearerToken}`);\n }\n normalized.headers = headers;\n }\n\n if (options.json !== undefined) {\n normalized.body = normalized.stringifyJson\n ? normalized.stringifyJson(options.json)\n : JSON.stringify(options.json);\n const headers = new Headers(normalized.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n normalized.headers = headers;\n }\n\n return normalized;\n}\n\n/**\n * @param {string} [method]\n * @returns {string}\n */\nexport function normalizeRequestMethod(method) {\n return (method ?? 'get').toLowerCase();\n}\n\n/**\n * @param {number} ms\n * @param {{ signal?: AbortSignal }} [options]\n * @returns {Promise<void>}\n */\nexport function delay(ms, options) {\n return new Promise((resolve, reject) => {\n const signal = options?.signal;\n\n if (signal?.aborted) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timer = setTimeout(resolve, ms);\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n }\n });\n}\n\n/**\n * Parse Retry-After from multiple common header formats.\n * @param {Response} response\n * @returns {number | undefined}\n */\nexport function parseRetryAfter(response) {\n const header =\n response.headers.get('retry-after') ??\n response.headers.get('ratelimit-reset') ??\n response.headers.get('x-ratelimit-retry-after') ??\n response.headers.get('x-ratelimit-reset') ??\n response.headers.get('x-rate-limit-reset');\n\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) {\n // Large numbers are treated as timestamps (threshold: 2024-01-01 epoch)\n if (seconds >= Date.parse('2024-01-01') / 1000) {\n return Math.max(0, seconds * 1000 - Date.now());\n }\n return seconds * 1000;\n }\n\n const date = Date.parse(header);\n if (!Number.isNaN(date)) {\n return Math.max(0, date - Date.now());\n }\n\n return undefined;\n}\n\n/**\n * Apply jitter to a delay value.\n * @param {number} delayMs\n * @param {boolean | ((delay: number) => number)} jitter\n * @returns {number}\n */\nexport function applyJitter(delayMs, jitter) {\n if (jitter === true) {\n return Math.random() * delayMs;\n }\n if (typeof jitter === 'function') {\n const result = jitter(delayMs);\n return Number.isFinite(result) && result >= 0 ? result : delayMs;\n }\n return delayMs;\n}\n\n/**\n * Check if error is a raw network error (TypeError from fetch).\n * @param {unknown} error\n * @returns {boolean}\n */\nexport function isNetworkError(error) {\n return (\n error instanceof TypeError &&\n (error.message === 'Failed to fetch' ||\n error.message === 'fetch failed' ||\n error.message === 'NetworkError when attempting to fetch resource.' ||\n error.message.includes('network') ||\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('ENOTFOUND') ||\n error.message.includes('ETIMEDOUT') ||\n error.message.includes('ECONNRESET'))\n );\n}\n","import { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nimport { RetryMarker } from './types.js';\nimport { stop } from './types.js';\nimport { streamResponse, streamRequest } from './stream.js';\nimport {\n appendSearchParams,\n resolveInput,\n delay,\n isNetworkError,\n applyJitter,\n parseRetryAfter,\n} from './utils.js';\nimport {\n maxSafeTimeout,\n responseTypes,\n supportsResponseStreams,\n supportsRequestStreams,\n} from './constants.js';\n\nconst invalidSchemaMessage = 'The `schema` argument must follow the Standard Schema specification';\n\n/**\n * @param {unknown} jsonValue\n * @param {any} schema\n * @returns {Promise<unknown>}\n */\nasync function validateJsonWithSchema(jsonValue, schema) {\n if ((typeof schema !== 'object' && typeof schema !== 'function') || schema === null) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const standardSchema = schema['~standard'];\n if (\n typeof standardSchema !== 'object' ||\n standardSchema === null ||\n typeof standardSchema.validate !== 'function'\n ) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const result = await standardSchema.validate(jsonValue);\n if (result.issues) {\n throw new SchemaValidationError(result.issues);\n }\n\n return result.value;\n}\n\n/**\n * @param {number | false} timeout\n * @param {AbortSignal} [userSignal]\n * @returns {{ signal: AbortSignal, cleanup: () => void }}\n */\nfunction createManagedSignal(timeout, userSignal) {\n const controller = new AbortController();\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let timer;\n\n if (timeout !== false && typeof timeout === 'number') {\n timer = setTimeout(() => controller.abort('timeout'), timeout);\n }\n\n if (userSignal) {\n if (userSignal.aborted) {\n controller.abort(userSignal.reason);\n } else {\n userSignal.addEventListener('abort', () => controller.abort(userSignal.reason), { once: true });\n }\n }\n\n return {\n signal: controller.signal,\n cleanup: () => {\n if (timer) clearTimeout(timer);\n },\n };\n}\n\n/**\n * Read response text with timeout and size limit.\n * @param {Response} response\n * @param {number} timeoutMs\n * @returns {Promise<string | undefined>}\n */\nasync function readResponseText(response, timeoutMs) {\n const { body } = response;\n if (!body) {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n }\n\n /** @type {ReadableStreamDefaultReader<Uint8Array>} */\n let reader;\n try {\n reader = body.getReader();\n } catch {\n return undefined;\n }\n\n const decoder = new TextDecoder();\n const chunks = [];\n let totalBytes = 0;\n const maxSize = 10 * 1024 * 1024;\n\n const readAll = (async () => {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n totalBytes += value.byteLength;\n if (totalBytes > maxSize) {\n void reader.cancel().catch(() => {});\n return undefined;\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n } catch {\n return undefined;\n }\n chunks.push(decoder.decode());\n return chunks.join('');\n })();\n\n const timeoutPromise = new Promise((resolve) => {\n const id = setTimeout(() => resolve(undefined), timeoutMs);\n void readAll.finally(() => clearTimeout(id));\n });\n\n const result = await Promise.race([readAll, timeoutPromise]);\n if (result === undefined) void reader.cancel().catch(() => {});\n return result;\n}\n\n/**\n * @param {Response} response\n * @param {number} timeoutMs\n * @param {any} options\n * @param {Request} request\n * @returns {Promise<unknown>}\n */\nasync function getResponseData(response, timeoutMs, options, request) {\n const text = await readResponseText(response, timeoutMs);\n if (!text) return undefined;\n\n const contentType = (response.headers.get('content-type') ?? '').split(';', 1)[0].trim().toLowerCase();\n const isJson = /\\/(?:.*[.+-])?json$/.test(contentType);\n if (!isJson) return text;\n\n try {\n return options.parseJson\n ? await options.parseJson(text, { request, response })\n : JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Strip internal-only options.\n * @param {any} options\n * @returns {any}\n */\nfunction getNormalizedOptions(options) {\n const {\n hooks, json, parseJson, stringifyJson, searchParams,\n timeout, totalTimeout, throwHttpErrors, fetch,\n context, _userSignal, prefix, baseUrl,\n onDownloadProgress, onUploadProgress, bearerToken,\n ...rest\n } = options;\n return Object.freeze(rest);\n}\n\n/**\n * Calculate retry delay.\n * @param {any} retry\n * @param {number} retryCount\n * @returns {number}\n */\nfunction calculateDelay(retry, retryCount) {\n const base = retry.delay(retryCount);\n const jittered = applyJitter(base, retry.jitter);\n return Math.min(retry.backoffLimit, jittered);\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {any} options\n * @returns {any}\n */\nexport function createResponsePromise(input, options) {\n // Run init hooks (synchronous, mutate options clone)\n for (const hook of options.hooks.init) {\n hook(options);\n }\n\n let retryCount = 0;\n const startTime = typeof options.totalTimeout === 'number' ? performance.now() : undefined;\n /** @type {Request} */\n let currentRequest;\n\n const getRemainingTotalTimeout = () => {\n if (startTime === undefined) return undefined;\n const elapsed = performance.now() - startTime;\n return Math.max(0, options.totalTimeout - elapsed);\n };\n\n const getEffectiveTimeout = () => {\n const remaining = getRemainingTotalTimeout();\n if (options.timeout === false) return remaining;\n if (remaining === undefined) return options.timeout;\n return Math.min(options.timeout, remaining);\n };\n\n const throwIfTotalTimeoutExhausted = () => {\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) {\n throw new TimeoutError(currentRequest);\n }\n };\n\n const innerPromise = (async () => {\n if (typeof options.timeout === 'number' && options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n if (typeof options.totalTimeout === 'number' && options.totalTimeout > maxSafeTimeout) {\n throw new RangeError(`The \\`totalTimeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n\n // Resolve URL\n const inputStr = resolveInput(input, { prefix: options.prefix, baseUrl: options.baseUrl });\n let url = new URL(inputStr);\n url = appendSearchParams(url, options.searchParams);\n\n // Build request init (strip neta-specific options)\n const {\n prefix: _prefix, baseUrl: _baseUrl, retry, timeout, totalTimeout,\n hooks, searchParams, json, throwHttpErrors, fetch: fetchFn,\n parseJson, stringifyJson, context, _userSignal,\n onDownloadProgress, onUploadProgress, bearerToken: _bearerToken,\n ...requestInit\n } = options;\n\n currentRequest = new Request(url.href, {\n ...requestInit,\n method: options.method.toUpperCase(),\n });\n\n // Defer so body shortcuts can set Accept header\n await Promise.resolve();\n\n // beforeRequest hooks\n for (const hook of hooks.beforeRequest) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n retryCount: 0,\n });\n\n if (result instanceof Response) return result;\n if (result instanceof Request) currentRequest = result;\n }\n\n const userSignal = options._userSignal;\n\n /**\n * Perform a single fetch attempt with timeout.\n * @returns {Promise<Response>}\n */\n const doFetch = async () => {\n const effectiveTimeout = getEffectiveTimeout();\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) throw new TimeoutError(currentRequest);\n\n const managed = createManagedSignal(effectiveTimeout, userSignal);\n\n let fetchRequest = currentRequest.clone();\n if (onUploadProgress && fetchRequest.body && supportsRequestStreams) {\n fetchRequest = streamRequest(fetchRequest, onUploadProgress, options.body);\n }\n\n try {\n const response = await fetchFn(fetchRequest, { signal: managed.signal });\n managed.cleanup();\n return response;\n } catch (error) {\n managed.cleanup();\n if (managed.signal.aborted && managed.signal.reason === 'timeout') {\n throw new TimeoutError(currentRequest);\n }\n if (isNetworkError(error)) {\n throw new NetworkError(currentRequest, { cause: error });\n }\n throw error;\n }\n };\n\n /**\n * Attempt retry: wait, run beforeRetry hooks, then fetch again.\n * @param {Error} error\n * @param {number} delayMs\n * @returns {Promise<Response | typeof stop>}\n */\n const attemptRetry = async (error, delayMs) => {\n const safeDelay = Math.min(delayMs, maxSafeTimeout);\n const delayOptions = { signal: userSignal };\n\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined) {\n if (remaining <= 0) throw new TimeoutError(currentRequest);\n if (safeDelay >= remaining) {\n await delay(remaining, delayOptions);\n throw new TimeoutError(currentRequest);\n }\n }\n\n await delay(safeDelay, delayOptions);\n throwIfTotalTimeoutExhausted();\n\n // Run beforeRetry hooks\n for (const hook of hooks.beforeRetry) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error,\n retryCount: retryCount + 1,\n });\n\n if (result instanceof Request) { currentRequest = result; break; }\n if (result instanceof Response) { retryCount++; return result; }\n if (result === stop) return stop;\n }\n\n throwIfTotalTimeoutExhausted();\n retryCount++;\n return doFetch();\n };\n\n /**\n * Check if we should retry a fetch-level error (timeout, network).\n * @param {Error} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForFetchError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof TimeoutError) {\n if (!retry.retryOnTimeout) throw error;\n return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof NetworkError) {\n return calculateDelay(retry, retryCount + 1);\n }\n\n throw error;\n };\n\n /**\n * Check if we should retry an HTTP error.\n * @param {HTTPError} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForHttpError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (!retry.statusCodes.includes(error.response.status)) throw error;\n\n // Handle Retry-After\n if (retry.afterStatusCodes.includes(error.response.status)) {\n const retryAfter = parseRetryAfter(error.response);\n if (retryAfter !== undefined) {\n return Math.min(retry.maxRetryAfter, Math.max(0, retryAfter));\n }\n }\n\n if (error.response.status === 413) throw error;\n\n return calculateDelay(retry, retryCount + 1);\n };\n\n // === Main request loop ===\n /** @type {Response} */\n let response;\n\n // Initial fetch with fetch-error retry loop\n for (;;) {\n try {\n response = await doFetch();\n break;\n } catch (error) {\n const retryDelay = await getRetryDelayForFetchError(error);\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) { response = retryResult; break; }\n }\n }\n\n // afterResponse hooks + HTTP error retry loop\n let responseFromHook = false;\n\n for (;;) {\n // Run afterResponse hooks\n try {\n for (const hook of hooks.afterResponse) {\n const clonedResponse = response.clone();\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n response: clonedResponse,\n retryCount,\n });\n\n if (hookResult instanceof RetryMarker) {\n throw new ForceRetryError(hookResult.options);\n }\n\n if (hookResult instanceof Response) {\n response = hookResult;\n }\n }\n } catch (error) {\n if (!(error instanceof ForceRetryError)) throw error;\n\n // Forced retry from afterResponse hook\n const retryDelay = error.customDelay ?? calculateDelay(retry, retryCount + 1);\n if (error.customRequest) currentRequest = error.customRequest;\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = true;\n continue;\n }\n continue;\n }\n\n // Check HTTP errors\n const shouldThrow = typeof throwHttpErrors === 'function'\n ? throwHttpErrors(response.status)\n : throwHttpErrors;\n\n if (!response.ok && response.type !== 'opaque' && shouldThrow) {\n const error = new HTTPError(response, currentRequest, getNormalizedOptions(options));\n error.data = await getResponseData(\n response,\n options.timeout === false ? 10_000 : options.timeout,\n options,\n currentRequest,\n );\n\n if (responseFromHook) throw error;\n\n // Try to retry\n let retryDelay;\n try {\n retryDelay = await getRetryDelayForHttpError(error);\n } catch {\n // Run beforeError hooks, then throw\n let processedError = error;\n for (const hook of hooks.beforeError) {\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error: processedError,\n retryCount,\n });\n if (hookResult instanceof Error) processedError = hookResult;\n }\n throw processedError;\n }\n\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = false; // Allow further retries\n continue;\n }\n continue;\n }\n\n break;\n }\n\n // Decorate response with custom parseJson\n if (options.parseJson) {\n response.json = async () => {\n const text = await response.clone().text();\n if (text === '') return JSON.parse(text);\n return options.parseJson(text, { request: currentRequest, response });\n };\n }\n\n // Handle download progress\n if (onDownloadProgress) {\n if (typeof onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported. `ReadableStream` is missing.');\n }\n return streamResponse(response, onDownloadProgress);\n }\n\n return response;\n })();\n\n // Build ResponsePromise thenable\n /** @type {any} */\n const responsePromise = {\n then: innerPromise.then.bind(innerPromise),\n catch: innerPromise.catch.bind(innerPromise),\n finally: innerPromise.finally.bind(innerPromise),\n [Symbol.toStringTag]: 'ResponsePromise',\n };\n\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n responsePromise[type] = async (schema) => {\n if (currentRequest) {\n currentRequest.headers.set('accept', currentRequest.headers.get('accept') || mimeType);\n }\n\n const response = await innerPromise;\n if (type !== 'json') return response[type]();\n\n const text = await response.text();\n if (text === '') {\n if (schema !== undefined) return validateJsonWithSchema(undefined, schema);\n return JSON.parse(text);\n }\n\n const jsonValue = options.parseJson\n ? await options.parseJson(text, { request: currentRequest, response })\n : JSON.parse(text);\n\n return schema === undefined ? jsonValue : validateJsonWithSchema(jsonValue, schema);\n };\n }\n\n return responsePromise;\n}\n"],"mappings":"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","names":["index_exports","__export","ForceRetryError","HTTPError","createInstance","NetworkError","SchemaValidationError","TimeoutError","index_default","neta","stop","__toCommonJS","HTTP_METHODS","DEFAULT_RETRY","attemptCount","DEFAULT_TIMEOUT","maxSafeTimeout","responseTypes","supportsAbortController","supportsAbortSignal","supportsFormData","supportsResponseStreams","supportsRequestStreams","duplexAccessed","hasContentType","HTTPError","response","request","options","status","TimeoutError","NetworkError","ForceRetryError","SchemaValidationError","issues","message","i","stop","RetryMarker","options","streamResponse","response","onDownloadProgress","totalBytes","transferredBytes","reader","stream","controller","done","value","percent","reason","streamRequest","request","onUploadProgress","originalBody","normalizeRetry","retry","DEFAULT_RETRY","normalizeHooks","hooks","mergeHeaders","target","source","result","value","key","mergeHooks","base","override","mergeOptions","defaults","overrides","merged","resolveInput","input","options","inputStr","prefix","path","appendSearchParams","url","searchParams","cleaned","params","normalizeOptions","normalized","normalizeRequestMethod","DEFAULT_TIMEOUT","headers","method","delay","ms","resolve","reject","signal","timer","parseRetryAfter","response","header","seconds","date","applyJitter","delayMs","jitter","isNetworkError","error","invalidSchemaMessage","validateJsonWithSchema","jsonValue","schema","standardSchema","result","SchemaValidationError","createManagedSignal","timeout","userSignal","controller","timer","readResponseText","response","timeoutMs","body","reader","decoder","chunks","totalBytes","maxSize","readAll","done","value","timeoutPromise","resolve","id","getResponseData","options","request","text","contentType","getNormalizedOptions","hooks","json","parseJson","stringifyJson","searchParams","totalTimeout","throwHttpErrors","fetch","context","_userSignal","prefix","baseUrl","onDownloadProgress","onUploadProgress","bearerToken","rest","calculateDelay","retry","retryCount","base","jittered","applyJitter","createResponsePromise","input","hook","startTime","currentRequest","getRemainingTotalTimeout","elapsed","getEffectiveTimeout","remaining","throwIfTotalTimeoutExhausted","TimeoutError","innerPromise","maxSafeTimeout","inputStr","resolveInput","url","appendSearchParams","_prefix","_baseUrl","fetchFn","_bearerToken","requestInit","doFetch","effectiveTimeout","managed","fetchRequest","supportsRequestStreams","streamRequest","error","isNetworkError","NetworkError","attemptRetry","delayMs","safeDelay","delayOptions","delay","stop","getRetryDelayForFetchError","getRetryDelayForHttpError","retryAfter","parseRetryAfter","retryDelay","retryResult","responseFromHook","clonedResponse","hookResult","RetryMarker","ForceRetryError","shouldThrow","HTTPError","processedError","supportsResponseStreams","streamResponse","responsePromise","type","mimeType","responseTypes","createInstance","defaults","fn","input","options","merged","mergeOptions","normalized","normalizeOptions","createResponsePromise","method","HTTP_METHODS","newDefaults","RetryMarker","neta","index_default"]}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var V=["get","post","put","patch","delete","head","options"],M={limit:2,methods:["get","put","head","delete","options"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:1/0,backoffLimit:1/0,delay:t=>300*2**(t-1),jitter:!1,retryOnTimeout:!1,shouldRetry:void 0},Y=1e4,E=2147483647,W={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*",bytes:"*/*"},Ne=typeof globalThis.AbortController=="function",Oe=typeof globalThis.AbortSignal<"u",Ue=typeof globalThis.FormData=="function",G=(()=>{try{return typeof globalThis.ReadableStream=="function"}catch{return!1}})(),K=(()=>{try{let t=!1,e=new Request(new URL("https://empty.invalid"),{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}catch{return!1}})();var S=class extends Error{constructor(e,r,o){let n=`${e.status}${e.statusText?` ${e.statusText}`:""}`;super(`Request failed with status code ${n}`),this.name="HTTPError",this.response=e,this.request=r,this.options=o,this.data=void 0}},b=class extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}},k=class extends Error{constructor(e,r){super("Network error",r),this.name="NetworkError",this.request=e}},q=class extends Error{constructor(e){super("Force retry"),this.name="ForceRetryError",this.customDelay=e?.delay,this.customRequest=e?.request}},U=class extends Error{constructor(e){let r=e.map(o=>o.message??"Unknown validation error").join("; ");super(`Schema validation failed: ${r}`),this.name="SchemaValidationError",this.issues=e}};var T=Symbol("neta.stop"),D=class{constructor(e){this.options=e}};function Q(t,e){let r=Number(t.headers.get("content-length"))||0,o=0,n=t.body.getReader(),i=new ReadableStream({async pull(p){let{done:y,value:d}=await n.read();if(y){e({percent:1,transferredBytes:o,totalBytes:r||o}),p.close();return}o+=d.byteLength;let R=r?o/r:0;e({percent:R,transferredBytes:o,totalBytes:r}),p.enqueue(d)},cancel(p){return n.cancel(p)}});return new Response(i,{status:t.status,statusText:t.statusText,headers:t.headers})}function X(t,e,r){let o=Number(t.headers.get("content-length"))||0,n=0,i=t.body.getReader(),p=new ReadableStream({async pull(y){let{done:d,value:R}=await i.read();if(d){e({percent:1,transferredBytes:n,totalBytes:o||n}),y.close();return}n+=R.byteLength;let u=o?n/o:0;e({percent:u,transferredBytes:n,totalBytes:o}),y.enqueue(R)},cancel(y){return i.cancel(y)}});return new Request(t.url,{method:t.method,headers:t.headers,body:p,duplex:"half",signal:t.signal})}function me(t){return typeof t=="number"?{...M,limit:t}:{...M,...t}}function he(t){return{init:[...t?.init??[]],beforeRequest:[...t?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[]],beforeError:[...t?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[]]}}function pe(t,e){let r=new Headers(t);return e&&new Headers(e).forEach((n,i)=>{r.set(i,n)}),r}function ye(t,e){return{init:[...t?.init??[],...e?.init??[]],beforeRequest:[...t?.beforeRequest??[],...e?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[],...e?.afterResponse??[]],beforeError:[...t?.beforeError??[],...e?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[],...e?.beforeRetry??[]]}}function _(t,e){if(!t)return e??{};if(!e)return t;let r={...t,...e};return(t.headers||e.headers)&&(r.headers=pe(t.headers,e.headers)),(t.hooks||e.hooks)&&(r.hooks=ye(t.hooks,e.hooks)),r}function Z(t,e){let r=t instanceof Request?t.url:String(t);if(e?.prefix){let o=String(e.prefix).replace(/\/+$/,""),n=r.replace(/^\/+/,"");r=`${o}/${n}`}if(e?.baseUrl)try{new URL(r)}catch{r=new URL(r,new Request(String(e.baseUrl)).url).href}return r}function ee(t,e){if(!e)return t;if(typeof e=="string"){let o=e.replace(/^\?/,"");return o&&(t.search=t.search?`${t.search}&${o}`:`?${o}`),t}let r;if(e instanceof URLSearchParams)r=e;else if(Array.isArray(e))r=new URLSearchParams(e);else{r=new URLSearchParams;for(let[o,n]of Object.entries(e))n!==void 0&&r.set(o,String(n))}return r.forEach((o,n)=>{t.searchParams.append(n,o)}),t}function te(t){let e={...t,method:we(t.method??"get"),retry:me(t.retry),timeout:t.timeout??Y,totalTimeout:t.totalTimeout??!1,hooks:he(t.hooks),throwHttpErrors:t.throwHttpErrors??!0,fetch:t.fetch??globalThis.fetch.bind(globalThis),context:t.context??{},prefix:t.prefix?String(t.prefix):""};if(t.json!==void 0){e.body=e.stringifyJson?e.stringifyJson(t.json):JSON.stringify(t.json);let r=new Headers(e.headers);r.has("content-type")||r.set("content-type","application/json"),e.headers=r}return e}function we(t){return(t??"get").toLowerCase()}function $(t,e){return new Promise((r,o)=>{let n=e?.signal;if(n?.aborted){o(n.reason??new DOMException("Aborted","AbortError"));return}let i=setTimeout(r,t);n&&n.addEventListener("abort",()=>{clearTimeout(i),o(n.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function re(t){let e=t.headers.get("retry-after")??t.headers.get("ratelimit-reset")??t.headers.get("x-ratelimit-retry-after")??t.headers.get("x-ratelimit-reset")??t.headers.get("x-rate-limit-reset");if(!e)return;let r=Number(e);if(!Number.isNaN(r))return r>=Date.parse("2024-01-01")/1e3?Math.max(0,r*1e3-Date.now()):r*1e3;let o=Date.parse(e);if(!Number.isNaN(o))return Math.max(0,o-Date.now())}function ne(t,e){if(e===!0)return Math.random()*t;if(typeof e=="function"){let r=e(t);return Number.isFinite(r)&&r>=0?r:t}return t}function oe(t){return t instanceof TypeError&&(t.message==="Failed to fetch"||t.message==="fetch failed"||t.message==="NetworkError when attempting to fetch resource."||t.message.includes("network")||t.message.includes("ECONNREFUSED")||t.message.includes("ENOTFOUND")||t.message.includes("ETIMEDOUT")||t.message.includes("ECONNRESET"))}var se="The `schema` argument must follow the Standard Schema specification";async function ae(t,e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError(se);let r=e["~standard"];if(typeof r!="object"||r===null||typeof r.validate!="function")throw new TypeError(se);let o=await r.validate(t);if(o.issues)throw new U(o.issues);return o.value}function Re(t,e){let r=new AbortController,o;return t!==!1&&typeof t=="number"&&(o=setTimeout(()=>r.abort("timeout"),t)),e&&(e.aborted?r.abort(e.reason):e.addEventListener("abort",()=>r.abort(e.reason),{once:!0})),{signal:r.signal,cleanup:()=>{o&&clearTimeout(o)}}}async function ge(t,e){let{body:r}=t;if(!r)try{return await t.text()}catch{return}let o;try{o=r.getReader()}catch{return}let n=new TextDecoder,i=[],p=0,y=10*1024*1024,d=(async()=>{try{for(;;){let{done:g,value:w}=await o.read();if(g)break;if(p+=w.byteLength,p>y){o.cancel().catch(()=>{});return}i.push(n.decode(w,{stream:!0}))}}catch{return}return i.push(n.decode()),i.join("")})(),R=new Promise(g=>{let w=setTimeout(()=>g(void 0),e);d.finally(()=>clearTimeout(w))}),u=await Promise.race([d,R]);return u===void 0&&o.cancel().catch(()=>{}),u}async function be(t,e,r,o){let n=await ge(t,e);if(!n)return;let i=(t.headers.get("content-type")??"").split(";",1)[0].trim().toLowerCase();if(!/\/(?:.*[.+-])?json$/.test(i))return n;try{return r.parseJson?await r.parseJson(n,{request:o,response:t}):JSON.parse(n)}catch{return}}function A(t){let{hooks:e,json:r,parseJson:o,stringifyJson:n,searchParams:i,timeout:p,totalTimeout:y,throwHttpErrors:d,fetch:R,context:u,_userSignal:g,prefix:w,baseUrl:O,onDownloadProgress:c,onUploadProgress:J,...v}=t;return Object.freeze(v)}function N(t,e){let r=t.delay(e),o=ne(r,t.jitter);return Math.min(t.backoffLimit,o)}function ie(t,e){for(let u of e.hooks.init)u(e);let r=0,o=typeof e.totalTimeout=="number"?performance.now():void 0,n,i=()=>{if(o===void 0)return;let u=performance.now()-o;return Math.max(0,e.totalTimeout-u)},p=()=>{let u=i();return e.timeout===!1?u:u===void 0?e.timeout:Math.min(e.timeout,u)},y=()=>{let u=i();if(u!==void 0&&u<=0)throw new b(n)},d=(async()=>{if(typeof e.timeout=="number"&&e.timeout>E)throw new RangeError(`The \`timeout\` option cannot be greater than ${E}`);if(typeof e.totalTimeout=="number"&&e.totalTimeout>E)throw new RangeError(`The \`totalTimeout\` option cannot be greater than ${E}`);let u=Z(t,{prefix:e.prefix,baseUrl:e.baseUrl}),g=new URL(u);g=ee(g,e.searchParams);let{prefix:w,baseUrl:O,retry:c,timeout:J,totalTimeout:v,hooks:H,searchParams:Te,json:Ee,throwHttpErrors:P,fetch:ue,parseJson:Se,stringifyJson:ke,context:qe,_userSignal:De,onDownloadProgress:C,onUploadProgress:z,...fe}=e;n=new Request(g.href,{...fe,method:e.method.toUpperCase()}),await Promise.resolve();for(let a of H.beforeRequest){let s=await a({request:n,options:A(e),retryCount:0});if(s instanceof Response)return s;s instanceof Request&&(n=s)}let I=e._userSignal,B=async()=>{let a=p(),s=i();if(s!==void 0&&s<=0)throw new b(n);let l=Re(a,I),f=n.clone();z&&f.body&&K&&(f=X(f,z,e.body));try{let h=await ue(f,{signal:l.signal});return l.cleanup(),h}catch(h){throw l.cleanup(),l.signal.aborted&&l.signal.reason==="timeout"?new b(n):oe(h)?new k(n,{cause:h}):h}},L=async(a,s)=>{let l=Math.min(s,E),f={signal:I},h=i();if(h!==void 0){if(h<=0)throw new b(n);if(l>=h)throw await $(h,f),new b(n)}await $(l,f),y();for(let F of H.beforeRetry){let x=await F({request:n,options:A(e),error:a,retryCount:r+1});if(x instanceof Request){n=x;break}if(x instanceof Response)return r++,x;if(x===T)return T}return y(),r++,B()},le=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return N(c,r+1)}if(a instanceof b){if(!c.retryOnTimeout)throw a;return N(c,r+1)}if(a instanceof k)return N(c,r+1);throw a},de=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return N(c,r+1)}if(!c.statusCodes.includes(a.response.status))throw a;if(c.afterStatusCodes.includes(a.response.status)){let s=re(a.response);if(s!==void 0)return Math.min(c.maxRetryAfter,Math.max(0,s))}if(a.response.status===413)throw a;return N(c,r+1)},m;for(;;)try{m=await B();break}catch(a){let s=await le(a),l=await L(a,s);if(l===T)return;if(l instanceof Response){m=l;break}}let j=!1;for(;;){try{for(let s of H.afterResponse){let l=m.clone(),f=await s({request:n,options:A(e),response:l,retryCount:r});if(f instanceof D)throw new q(f.options);f instanceof Response&&(m=f)}}catch(s){if(!(s instanceof q))throw s;let l=s.customDelay??N(c,r+1);s.customRequest&&(n=s.customRequest);let f=await L(s,l);if(f===T)return;if(f instanceof Response){m=f,j=!0;continue}continue}let a=typeof P=="function"?P(m.status):P;if(!m.ok&&m.type!=="opaque"&&a){let s=new S(m,n,A(e));if(s.data=await be(m,e.timeout===!1?1e4:e.timeout,e,n),j)throw s;let l;try{l=await de(s)}catch{let h=s;for(let F of H.beforeError){let x=await F({request:n,options:A(e),error:h,retryCount:r});x instanceof Error&&(h=x)}throw h}let f=await L(s,l);if(f===T)return;if(f instanceof Response){m=f,j=!1;continue}continue}break}if(e.parseJson&&(m.json=async()=>{let a=await m.clone().text();return a===""?JSON.parse(a):e.parseJson(a,{request:n,response:m})}),C){if(typeof C!="function")throw new TypeError("The `onDownloadProgress` option must be a function");if(!G)throw new Error("Streams are not supported. `ReadableStream` is missing.");return Q(m,C)}return m})(),R={then:d.then.bind(d),catch:d.catch.bind(d),finally:d.finally.bind(d),[Symbol.toStringTag]:"ResponsePromise"};for(let[u,g]of Object.entries(W))R[u]=async w=>{n&&n.headers.set("accept",n.headers.get("accept")||g);let O=await d;if(u!=="json")return O[u]();let c=await O.text();if(c==="")return w!==void 0?ae(void 0,w):JSON.parse(c);let J=e.parseJson?await e.parseJson(c,{request:n,response:O}):JSON.parse(c);return w===void 0?J:ae(J,w)};return R}function ce(t){let e=(r,o)=>{let n=_(t,o),i=te(n);return i._userSignal=i.signal??void 0,ie(r,i)};for(let r of V)e[r]=(o,n)=>e(o,{...n,method:r});return e.create=r=>ce(_(t,r)),e.extend=e.create,e.retry=r=>new D(r),e}var xe=ce(),We=xe;export{q as ForceRetryError,S as HTTPError,ce as NetaClient,S as NetaError,k as NetworkError,U as SchemaValidationError,b as TimeoutError,ce as createInstance,We as default,xe as neta,T as stop};
|
|
1
|
+
var I=["get","post","put","patch","delete","head","options"],_={limit:2,methods:["get","put","head","delete","options"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:[413,429,503],maxRetryAfter:1/0,backoffLimit:1/0,delay:t=>300*2**(t-1),jitter:!1,retryOnTimeout:!1,shouldRetry:void 0},V=1e4,S=2147483647,Y={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*",bytes:"*/*"},Oe=typeof globalThis.AbortController=="function",Ue=typeof globalThis.AbortSignal<"u",Ae=typeof globalThis.FormData=="function",W=(()=>{try{return typeof globalThis.ReadableStream=="function"}catch{return!1}})(),G=(()=>{try{let t=!1,e=new Request(new URL("https://empty.invalid"),{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}catch{return!1}})();var k=class extends Error{constructor(e,r,o){let n=`${e.status}${e.statusText?` ${e.statusText}`:""}`;super(`Request failed with status code ${n}`),this.name="HTTPError",this.response=e,this.request=r,this.options=o,this.data=void 0}},g=class extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}},q=class extends Error{constructor(e,r){super("Network error",r),this.name="NetworkError",this.request=e}},D=class extends Error{constructor(e){super("Force retry"),this.name="ForceRetryError",this.customDelay=e?.delay,this.customRequest=e?.request}},A=class extends Error{constructor(e){let r=e.map(o=>o.message??"Unknown validation error").join("; ");super(`Schema validation failed: ${r}`),this.name="SchemaValidationError",this.issues=e}};var T=Symbol("neta.stop"),N=class{constructor(e){this.options=e}};function K(t,e){let r=Number(t.headers.get("content-length"))||0,o=0,n=t.body.getReader(),i=new ReadableStream({async pull(p){let{done:y,value:l}=await n.read();if(y){e({percent:1,transferredBytes:o,totalBytes:r||o}),p.close();return}o+=l.byteLength;let b=r?o/r:0;e({percent:b,transferredBytes:o,totalBytes:r}),p.enqueue(l)},cancel(p){return n.cancel(p)}});return new Response(i,{status:t.status,statusText:t.statusText,headers:t.headers})}function Q(t,e,r){let o=Number(t.headers.get("content-length"))||0,n=0,i=t.body.getReader(),p=new ReadableStream({async pull(y){let{done:l,value:b}=await i.read();if(l){e({percent:1,transferredBytes:n,totalBytes:o||n}),y.close();return}n+=b.byteLength;let u=o?n/o:0;e({percent:u,transferredBytes:n,totalBytes:o}),y.enqueue(b)},cancel(y){return i.cancel(y)}});return new Request(t.url,{method:t.method,headers:t.headers,body:p,duplex:"half",signal:t.signal})}function me(t){return typeof t=="number"?{..._,limit:t}:{..._,...t}}function he(t){return{init:[...t?.init??[]],beforeRequest:[...t?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[]],beforeError:[...t?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[]]}}function pe(t,e){let r=new Headers(t);return e&&new Headers(e).forEach((n,i)=>{r.set(i,n)}),r}function ye(t,e){return{init:[...t?.init??[],...e?.init??[]],beforeRequest:[...t?.beforeRequest??[],...e?.beforeRequest??[]],afterResponse:[...t?.afterResponse??[],...e?.afterResponse??[]],beforeError:[...t?.beforeError??[],...e?.beforeError??[]],beforeRetry:[...t?.beforeRetry??[],...e?.beforeRetry??[]]}}function M(t,e){if(!t)return e??{};if(!e)return t;let r={...t,...e};return(t.headers||e.headers)&&(r.headers=pe(t.headers,e.headers)),(t.hooks||e.hooks)&&(r.hooks=ye(t.hooks,e.hooks)),r}function X(t,e){let r=t instanceof Request?t.url:String(t);if(e?.prefix){let o=String(e.prefix).replace(/\/+$/,""),n=r.replace(/^\/+/,"");r=`${o}/${n}`}if(e?.baseUrl)try{new URL(r)}catch{r=new URL(r,new Request(String(e.baseUrl)).url).href}return r}function Z(t,e){if(!e)return t;if(typeof e=="string"){let o=e.replace(/^\?/,"");return o&&(t.search=t.search?`${t.search}&${o}`:`?${o}`),t}let r;if(e instanceof URLSearchParams)r=e;else if(Array.isArray(e))r=new URLSearchParams(e);else{r=new URLSearchParams;for(let[o,n]of Object.entries(e))n!==void 0&&r.set(o,String(n))}return r.forEach((o,n)=>{t.searchParams.append(n,o)}),t}function ee(t){let e={...t,method:we(t.method??"get"),retry:me(t.retry),timeout:t.timeout??V,totalTimeout:t.totalTimeout??!1,hooks:he(t.hooks),throwHttpErrors:t.throwHttpErrors??!0,fetch:t.fetch??globalThis.fetch.bind(globalThis),context:t.context??{},prefix:t.prefix?String(t.prefix):""};if(t.bearerToken!==void 0){let r=new Headers(e.headers);r.has("authorization")||r.set("authorization",`Bearer ${t.bearerToken}`),e.headers=r}if(t.json!==void 0){e.body=e.stringifyJson?e.stringifyJson(t.json):JSON.stringify(t.json);let r=new Headers(e.headers);r.has("content-type")||r.set("content-type","application/json"),e.headers=r}return e}function we(t){return(t??"get").toLowerCase()}function $(t,e){return new Promise((r,o)=>{let n=e?.signal;if(n?.aborted){o(n.reason??new DOMException("Aborted","AbortError"));return}let i=setTimeout(r,t);n&&n.addEventListener("abort",()=>{clearTimeout(i),o(n.reason??new DOMException("Aborted","AbortError"))},{once:!0})})}function te(t){let e=t.headers.get("retry-after")??t.headers.get("ratelimit-reset")??t.headers.get("x-ratelimit-retry-after")??t.headers.get("x-ratelimit-reset")??t.headers.get("x-rate-limit-reset");if(!e)return;let r=Number(e);if(!Number.isNaN(r))return r>=Date.parse("2024-01-01")/1e3?Math.max(0,r*1e3-Date.now()):r*1e3;let o=Date.parse(e);if(!Number.isNaN(o))return Math.max(0,o-Date.now())}function re(t,e){if(e===!0)return Math.random()*t;if(typeof e=="function"){let r=e(t);return Number.isFinite(r)&&r>=0?r:t}return t}function ne(t){return t instanceof TypeError&&(t.message==="Failed to fetch"||t.message==="fetch failed"||t.message==="NetworkError when attempting to fetch resource."||t.message.includes("network")||t.message.includes("ECONNREFUSED")||t.message.includes("ENOTFOUND")||t.message.includes("ETIMEDOUT")||t.message.includes("ECONNRESET"))}var oe="The `schema` argument must follow the Standard Schema specification";async function se(t,e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError(oe);let r=e["~standard"];if(typeof r!="object"||r===null||typeof r.validate!="function")throw new TypeError(oe);let o=await r.validate(t);if(o.issues)throw new A(o.issues);return o.value}function be(t,e){let r=new AbortController,o;return t!==!1&&typeof t=="number"&&(o=setTimeout(()=>r.abort("timeout"),t)),e&&(e.aborted?r.abort(e.reason):e.addEventListener("abort",()=>r.abort(e.reason),{once:!0})),{signal:r.signal,cleanup:()=>{o&&clearTimeout(o)}}}async function Re(t,e){let{body:r}=t;if(!r)try{return await t.text()}catch{return}let o;try{o=r.getReader()}catch{return}let n=new TextDecoder,i=[],p=0,y=10*1024*1024,l=(async()=>{try{for(;;){let{done:R,value:w}=await o.read();if(R)break;if(p+=w.byteLength,p>y){o.cancel().catch(()=>{});return}i.push(n.decode(w,{stream:!0}))}}catch{return}return i.push(n.decode()),i.join("")})(),b=new Promise(R=>{let w=setTimeout(()=>R(void 0),e);l.finally(()=>clearTimeout(w))}),u=await Promise.race([l,b]);return u===void 0&&o.cancel().catch(()=>{}),u}async function ge(t,e,r,o){let n=await Re(t,e);if(!n)return;let i=(t.headers.get("content-type")??"").split(";",1)[0].trim().toLowerCase();if(!/\/(?:.*[.+-])?json$/.test(i))return n;try{return r.parseJson?await r.parseJson(n,{request:o,response:t}):JSON.parse(n)}catch{return}}function H(t){let{hooks:e,json:r,parseJson:o,stringifyJson:n,searchParams:i,timeout:p,totalTimeout:y,throwHttpErrors:l,fetch:b,context:u,_userSignal:R,prefix:w,baseUrl:U,onDownloadProgress:c,onUploadProgress:J,bearerToken:ce,...E}=t;return Object.freeze(E)}function O(t,e){let r=t.delay(e),o=re(r,t.jitter);return Math.min(t.backoffLimit,o)}function ae(t,e){for(let u of e.hooks.init)u(e);let r=0,o=typeof e.totalTimeout=="number"?performance.now():void 0,n,i=()=>{if(o===void 0)return;let u=performance.now()-o;return Math.max(0,e.totalTimeout-u)},p=()=>{let u=i();return e.timeout===!1?u:u===void 0?e.timeout:Math.min(e.timeout,u)},y=()=>{let u=i();if(u!==void 0&&u<=0)throw new g(n)},l=(async()=>{if(typeof e.timeout=="number"&&e.timeout>S)throw new RangeError(`The \`timeout\` option cannot be greater than ${S}`);if(typeof e.totalTimeout=="number"&&e.totalTimeout>S)throw new RangeError(`The \`totalTimeout\` option cannot be greater than ${S}`);let u=X(t,{prefix:e.prefix,baseUrl:e.baseUrl}),R=new URL(u);R=Z(R,e.searchParams);let{prefix:w,baseUrl:U,retry:c,timeout:J,totalTimeout:ce,hooks:E,searchParams:Te,json:Ee,throwHttpErrors:P,fetch:ue,parseJson:Se,stringifyJson:ke,context:qe,_userSignal:De,onDownloadProgress:C,onUploadProgress:v,bearerToken:Ne,...fe}=e;n=new Request(R.href,{...fe,method:e.method.toUpperCase()}),await Promise.resolve();for(let a of E.beforeRequest){let s=await a({request:n,options:H(e),retryCount:0});if(s instanceof Response)return s;s instanceof Request&&(n=s)}let z=e._userSignal,B=async()=>{let a=p(),s=i();if(s!==void 0&&s<=0)throw new g(n);let d=be(a,z),f=n.clone();v&&f.body&&G&&(f=Q(f,v,e.body));try{let h=await ue(f,{signal:d.signal});return d.cleanup(),h}catch(h){throw d.cleanup(),d.signal.aborted&&d.signal.reason==="timeout"?new g(n):ne(h)?new q(n,{cause:h}):h}},L=async(a,s)=>{let d=Math.min(s,S),f={signal:z},h=i();if(h!==void 0){if(h<=0)throw new g(n);if(d>=h)throw await $(h,f),new g(n)}await $(d,f),y();for(let F of E.beforeRetry){let x=await F({request:n,options:H(e),error:a,retryCount:r+1});if(x instanceof Request){n=x;break}if(x instanceof Response)return r++,x;if(x===T)return T}return y(),r++,B()},de=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return O(c,r+1)}if(a instanceof g){if(!c.retryOnTimeout)throw a;return O(c,r+1)}if(a instanceof q)return O(c,r+1);throw a},le=async a=>{if(r>=c.limit||!c.methods.includes(e.method))throw a;if(c.shouldRetry!==void 0){let s=await c.shouldRetry({error:a,retryCount:r+1});if(s===!1)throw a;if(s===!0)return O(c,r+1)}if(!c.statusCodes.includes(a.response.status))throw a;if(c.afterStatusCodes.includes(a.response.status)){let s=te(a.response);if(s!==void 0)return Math.min(c.maxRetryAfter,Math.max(0,s))}if(a.response.status===413)throw a;return O(c,r+1)},m;for(;;)try{m=await B();break}catch(a){let s=await de(a),d=await L(a,s);if(d===T)return;if(d instanceof Response){m=d;break}}let j=!1;for(;;){try{for(let s of E.afterResponse){let d=m.clone(),f=await s({request:n,options:H(e),response:d,retryCount:r});if(f instanceof N)throw new D(f.options);f instanceof Response&&(m=f)}}catch(s){if(!(s instanceof D))throw s;let d=s.customDelay??O(c,r+1);s.customRequest&&(n=s.customRequest);let f=await L(s,d);if(f===T)return;if(f instanceof Response){m=f,j=!0;continue}continue}let a=typeof P=="function"?P(m.status):P;if(!m.ok&&m.type!=="opaque"&&a){let s=new k(m,n,H(e));if(s.data=await ge(m,e.timeout===!1?1e4:e.timeout,e,n),j)throw s;let d;try{d=await le(s)}catch{let h=s;for(let F of E.beforeError){let x=await F({request:n,options:H(e),error:h,retryCount:r});x instanceof Error&&(h=x)}throw h}let f=await L(s,d);if(f===T)return;if(f instanceof Response){m=f,j=!1;continue}continue}break}if(e.parseJson&&(m.json=async()=>{let a=await m.clone().text();return a===""?JSON.parse(a):e.parseJson(a,{request:n,response:m})}),C){if(typeof C!="function")throw new TypeError("The `onDownloadProgress` option must be a function");if(!W)throw new Error("Streams are not supported. `ReadableStream` is missing.");return K(m,C)}return m})(),b={then:l.then.bind(l),catch:l.catch.bind(l),finally:l.finally.bind(l),[Symbol.toStringTag]:"ResponsePromise"};for(let[u,R]of Object.entries(Y))b[u]=async w=>{n&&n.headers.set("accept",n.headers.get("accept")||R);let U=await l;if(u!=="json")return U[u]();let c=await U.text();if(c==="")return w!==void 0?se(void 0,w):JSON.parse(c);let J=e.parseJson?await e.parseJson(c,{request:n,response:U}):JSON.parse(c);return w===void 0?J:se(J,w)};return b}function ie(t){let e=(r,o)=>{let n=M(t,o),i=ee(n);return i._userSignal=i.signal??void 0,ae(r,i)};for(let r of I)e[r]=(o,n)=>e(o,{...n,method:r});return e.create=r=>ie(M(t,r)),e.extend=e.create,e.retry=r=>new N(r),e}var xe=ie(),Ge=xe;export{D as ForceRetryError,k as HTTPError,ie as NetaClient,k as NetaError,q as NetworkError,A as SchemaValidationError,g as TimeoutError,ie as createInstance,Ge as default,xe as neta,T as stop};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.js","../src/errors.js","../src/types.js","../src/stream.js","../src/utils.js","../src/core.js","../src/index.js"],"sourcesContent":["/** @type {import('../types/types.js').HttpMethod[]} */\nexport const HTTP_METHODS = [\n 'get', 'post', 'put', 'patch', 'delete', 'head', 'options',\n];\n\n/** @type {import('../types/types.js').RetryOptions} */\nexport const DEFAULT_RETRY = {\n limit: 2,\n methods: ['get', 'put', 'head', 'delete', 'options'],\n statusCodes: [408, 413, 429, 500, 502, 503, 504],\n afterStatusCodes: [413, 429, 503],\n maxRetryAfter: Infinity,\n backoffLimit: Infinity,\n delay: (attemptCount) => 300 * 2 ** (attemptCount - 1),\n jitter: false,\n retryOnTimeout: false,\n shouldRetry: undefined,\n};\n\nexport const DEFAULT_TIMEOUT = 10_000;\n\nexport const maxSafeTimeout = 2_147_483_647; // 2^31 - 1\n\n/** @type {Record<string, string>} */\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n bytes: '*/*',\n};\n\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal !== 'undefined';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\n\nexport const supportsResponseStreams = (() => {\n try {\n return typeof globalThis.ReadableStream === 'function';\n } catch {\n return false;\n }\n})();\n\nexport const supportsRequestStreams = (() => {\n try {\n let duplexAccessed = false;\n const hasContentType = new Request(\n new URL('https://empty.invalid'),\n {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n },\n ).headers.has('Content-Type');\n return duplexAccessed && !hasContentType;\n } catch {\n return false;\n }\n})();\n","export class HTTPError extends Error {\n /**\n * @param {Response} response\n * @param {Request} request\n * @param {import('./types.js').NormalizedOptions} options\n */\n constructor(response, request, options) {\n const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ''}`;\n super(`Request failed with status code ${status}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n /** @type {unknown} */\n this.data = undefined;\n }\n}\n\nexport class TimeoutError extends Error {\n /**\n * @param {Request} request\n */\n constructor(request) {\n super('Request timed out');\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n\nexport class NetworkError extends Error {\n /**\n * @param {Request} request\n * @param {{ cause?: Error }} [options]\n */\n constructor(request, options) {\n super('Network error', options);\n this.name = 'NetworkError';\n this.request = request;\n }\n}\n\nexport class ForceRetryError extends Error {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n super('Force retry');\n this.name = 'ForceRetryError';\n this.customDelay = options?.delay;\n this.customRequest = options?.request;\n }\n}\n\nexport class SchemaValidationError extends Error {\n /**\n * @param {Array<{ message?: string, path?: Array<string | number | symbol> }>} issues\n */\n constructor(issues) {\n const message = issues.map((i) => i.message ?? 'Unknown validation error').join('; ');\n super(`Schema validation failed: ${message}`);\n this.name = 'SchemaValidationError';\n this.issues = issues;\n }\n}\n","/** @type {unique symbol} */\nexport const stop = Symbol('neta.stop');\n\nexport class RetryMarker {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n this.options = options;\n }\n}\n","/**\n * @param {Response} response\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onDownloadProgress\n * @returns {Response}\n */\nexport function streamResponse(response, onDownloadProgress) {\n const totalBytes = Number(response.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = response.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onDownloadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onDownloadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n}\n\n/**\n * @param {Request} request\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onUploadProgress\n * @param {BodyInit} [originalBody]\n * @returns {Request}\n */\nexport function streamRequest(request, onUploadProgress, originalBody) {\n const totalBytes = Number(request.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = request.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onUploadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onUploadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n duplex: 'half',\n signal: request.signal,\n });\n}\n","import { DEFAULT_RETRY, DEFAULT_TIMEOUT } from './constants.js';\n\n/**\n * @param {import('../types/types.js').Options['retry']} retry\n * @returns {import('../types/types.js').RetryOptions}\n */\nexport function normalizeRetry(retry) {\n if (typeof retry === 'number') {\n return { ...DEFAULT_RETRY, limit: retry };\n }\n return { ...DEFAULT_RETRY, ...retry };\n}\n\n/**\n * @param {import('../types/types.js').Hooks} [hooks]\n * @returns {import('../types/types.js').NormalizedHooks}\n */\nexport function normalizeHooks(hooks) {\n return {\n init: [...(hooks?.init ?? [])],\n beforeRequest: [...(hooks?.beforeRequest ?? [])],\n afterResponse: [...(hooks?.afterResponse ?? [])],\n beforeError: [...(hooks?.beforeError ?? [])],\n beforeRetry: [...(hooks?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {HeadersInit} [target]\n * @param {HeadersInit} [source]\n * @returns {Headers}\n */\nexport function mergeHeaders(target, source) {\n const result = new Headers(target);\n if (source) {\n const sourceHeaders = new Headers(source);\n sourceHeaders.forEach((value, key) => {\n result.set(key, value);\n });\n }\n return result;\n}\n\n/**\n * Merge hooks by concatenating arrays.\n * @param {import('../types/types.js').Hooks} [base]\n * @param {import('../types/types.js').Hooks} [override]\n * @returns {import('../types/types.js').Hooks}\n */\nexport function mergeHooks(base, override) {\n return {\n init: [...(base?.init ?? []), ...(override?.init ?? [])],\n beforeRequest: [...(base?.beforeRequest ?? []), ...(override?.beforeRequest ?? [])],\n afterResponse: [...(base?.afterResponse ?? []), ...(override?.afterResponse ?? [])],\n beforeError: [...(base?.beforeError ?? []), ...(override?.beforeError ?? [])],\n beforeRetry: [...(base?.beforeRetry ?? []), ...(override?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @param {import('../types/types.js').Options} [overrides]\n * @returns {import('../types/types.js').Options}\n */\nexport function mergeOptions(defaults, overrides) {\n if (!defaults) return overrides ?? {};\n if (!overrides) return defaults;\n\n const merged = { ...defaults, ...overrides };\n\n if (defaults.headers || overrides.headers) {\n merged.headers = mergeHeaders(defaults.headers, overrides.headers);\n }\n\n if (defaults.hooks || overrides.hooks) {\n merged.hooks = mergeHooks(defaults.hooks, overrides.hooks);\n }\n\n return merged;\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {{ prefix?: string, baseUrl?: string | URL }} [options]\n * @returns {string}\n */\nexport function resolveInput(input, options) {\n let inputStr = input instanceof Request ? input.url : String(input);\n\n if (options?.prefix) {\n const prefix = String(options.prefix).replace(/\\/+$/, '');\n const path = inputStr.replace(/^\\/+/, '');\n inputStr = `${prefix}/${path}`;\n }\n\n if (options?.baseUrl) {\n try {\n // If already absolute, keep as-is\n new URL(inputStr);\n } catch {\n // Relative — resolve against baseUrl\n inputStr = new URL(inputStr, new Request(String(options.baseUrl)).url).href;\n }\n }\n\n return inputStr;\n}\n\n/**\n * @param {URL} url\n * @param {import('../types/types.js').SearchParamsInit} [searchParams]\n * @returns {URL}\n */\nexport function appendSearchParams(url, searchParams) {\n if (!searchParams) return url;\n\n if (typeof searchParams === 'string') {\n const cleaned = searchParams.replace(/^\\?/, '');\n if (cleaned) {\n url.search = url.search ? `${url.search}&${cleaned}` : `?${cleaned}`;\n }\n return url;\n }\n\n /** @type {URLSearchParams} */\n let params;\n\n if (searchParams instanceof URLSearchParams) {\n params = searchParams;\n } else if (Array.isArray(searchParams)) {\n params = new URLSearchParams(searchParams);\n } else {\n params = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n }\n\n params.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n return url;\n}\n\n/**\n * @param {import('../types/types.js').Options} options\n * @returns {import('../types/types.js').InternalOptions}\n */\nexport function normalizeOptions(options) {\n const normalized = {\n ...options,\n method: normalizeRequestMethod(options.method ?? 'get'),\n retry: normalizeRetry(options.retry),\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n totalTimeout: options.totalTimeout ?? false,\n hooks: normalizeHooks(options.hooks),\n throwHttpErrors: options.throwHttpErrors ?? true,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n prefix: options.prefix ? String(options.prefix) : '',\n };\n\n if (options.json !== undefined) {\n normalized.body = normalized.stringifyJson\n ? normalized.stringifyJson(options.json)\n : JSON.stringify(options.json);\n const headers = new Headers(normalized.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n normalized.headers = headers;\n }\n\n return normalized;\n}\n\n/**\n * @param {string} [method]\n * @returns {string}\n */\nexport function normalizeRequestMethod(method) {\n return (method ?? 'get').toLowerCase();\n}\n\n/**\n * @param {number} ms\n * @param {{ signal?: AbortSignal }} [options]\n * @returns {Promise<void>}\n */\nexport function delay(ms, options) {\n return new Promise((resolve, reject) => {\n const signal = options?.signal;\n\n if (signal?.aborted) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timer = setTimeout(resolve, ms);\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n }\n });\n}\n\n/**\n * Parse Retry-After from multiple common header formats.\n * @param {Response} response\n * @returns {number | undefined}\n */\nexport function parseRetryAfter(response) {\n const header =\n response.headers.get('retry-after') ??\n response.headers.get('ratelimit-reset') ??\n response.headers.get('x-ratelimit-retry-after') ??\n response.headers.get('x-ratelimit-reset') ??\n response.headers.get('x-rate-limit-reset');\n\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) {\n // Large numbers are treated as timestamps (threshold: 2024-01-01 epoch)\n if (seconds >= Date.parse('2024-01-01') / 1000) {\n return Math.max(0, seconds * 1000 - Date.now());\n }\n return seconds * 1000;\n }\n\n const date = Date.parse(header);\n if (!Number.isNaN(date)) {\n return Math.max(0, date - Date.now());\n }\n\n return undefined;\n}\n\n/**\n * Apply jitter to a delay value.\n * @param {number} delayMs\n * @param {boolean | ((delay: number) => number)} jitter\n * @returns {number}\n */\nexport function applyJitter(delayMs, jitter) {\n if (jitter === true) {\n return Math.random() * delayMs;\n }\n if (typeof jitter === 'function') {\n const result = jitter(delayMs);\n return Number.isFinite(result) && result >= 0 ? result : delayMs;\n }\n return delayMs;\n}\n\n/**\n * Check if error is a raw network error (TypeError from fetch).\n * @param {unknown} error\n * @returns {boolean}\n */\nexport function isNetworkError(error) {\n return (\n error instanceof TypeError &&\n (error.message === 'Failed to fetch' ||\n error.message === 'fetch failed' ||\n error.message === 'NetworkError when attempting to fetch resource.' ||\n error.message.includes('network') ||\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('ENOTFOUND') ||\n error.message.includes('ETIMEDOUT') ||\n error.message.includes('ECONNRESET'))\n );\n}\n","import { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nimport { RetryMarker } from './types.js';\nimport { stop } from './types.js';\nimport { streamResponse, streamRequest } from './stream.js';\nimport {\n appendSearchParams,\n resolveInput,\n delay,\n isNetworkError,\n applyJitter,\n parseRetryAfter,\n} from './utils.js';\nimport {\n maxSafeTimeout,\n responseTypes,\n supportsResponseStreams,\n supportsRequestStreams,\n} from './constants.js';\n\nconst invalidSchemaMessage = 'The `schema` argument must follow the Standard Schema specification';\n\n/**\n * @param {unknown} jsonValue\n * @param {any} schema\n * @returns {Promise<unknown>}\n */\nasync function validateJsonWithSchema(jsonValue, schema) {\n if ((typeof schema !== 'object' && typeof schema !== 'function') || schema === null) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const standardSchema = schema['~standard'];\n if (\n typeof standardSchema !== 'object' ||\n standardSchema === null ||\n typeof standardSchema.validate !== 'function'\n ) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const result = await standardSchema.validate(jsonValue);\n if (result.issues) {\n throw new SchemaValidationError(result.issues);\n }\n\n return result.value;\n}\n\n/**\n * @param {number | false} timeout\n * @param {AbortSignal} [userSignal]\n * @returns {{ signal: AbortSignal, cleanup: () => void }}\n */\nfunction createManagedSignal(timeout, userSignal) {\n const controller = new AbortController();\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let timer;\n\n if (timeout !== false && typeof timeout === 'number') {\n timer = setTimeout(() => controller.abort('timeout'), timeout);\n }\n\n if (userSignal) {\n if (userSignal.aborted) {\n controller.abort(userSignal.reason);\n } else {\n userSignal.addEventListener('abort', () => controller.abort(userSignal.reason), { once: true });\n }\n }\n\n return {\n signal: controller.signal,\n cleanup: () => {\n if (timer) clearTimeout(timer);\n },\n };\n}\n\n/**\n * Read response text with timeout and size limit.\n * @param {Response} response\n * @param {number} timeoutMs\n * @returns {Promise<string | undefined>}\n */\nasync function readResponseText(response, timeoutMs) {\n const { body } = response;\n if (!body) {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n }\n\n /** @type {ReadableStreamDefaultReader<Uint8Array>} */\n let reader;\n try {\n reader = body.getReader();\n } catch {\n return undefined;\n }\n\n const decoder = new TextDecoder();\n const chunks = [];\n let totalBytes = 0;\n const maxSize = 10 * 1024 * 1024;\n\n const readAll = (async () => {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n totalBytes += value.byteLength;\n if (totalBytes > maxSize) {\n void reader.cancel().catch(() => {});\n return undefined;\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n } catch {\n return undefined;\n }\n chunks.push(decoder.decode());\n return chunks.join('');\n })();\n\n const timeoutPromise = new Promise((resolve) => {\n const id = setTimeout(() => resolve(undefined), timeoutMs);\n void readAll.finally(() => clearTimeout(id));\n });\n\n const result = await Promise.race([readAll, timeoutPromise]);\n if (result === undefined) void reader.cancel().catch(() => {});\n return result;\n}\n\n/**\n * @param {Response} response\n * @param {number} timeoutMs\n * @param {any} options\n * @param {Request} request\n * @returns {Promise<unknown>}\n */\nasync function getResponseData(response, timeoutMs, options, request) {\n const text = await readResponseText(response, timeoutMs);\n if (!text) return undefined;\n\n const contentType = (response.headers.get('content-type') ?? '').split(';', 1)[0].trim().toLowerCase();\n const isJson = /\\/(?:.*[.+-])?json$/.test(contentType);\n if (!isJson) return text;\n\n try {\n return options.parseJson\n ? await options.parseJson(text, { request, response })\n : JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Strip internal-only options.\n * @param {any} options\n * @returns {any}\n */\nfunction getNormalizedOptions(options) {\n const {\n hooks, json, parseJson, stringifyJson, searchParams,\n timeout, totalTimeout, throwHttpErrors, fetch,\n context, _userSignal, prefix, baseUrl,\n onDownloadProgress, onUploadProgress,\n ...rest\n } = options;\n return Object.freeze(rest);\n}\n\n/**\n * Calculate retry delay.\n * @param {any} retry\n * @param {number} retryCount\n * @returns {number}\n */\nfunction calculateDelay(retry, retryCount) {\n const base = retry.delay(retryCount);\n const jittered = applyJitter(base, retry.jitter);\n return Math.min(retry.backoffLimit, jittered);\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {any} options\n * @returns {any}\n */\nexport function createResponsePromise(input, options) {\n // Run init hooks (synchronous, mutate options clone)\n for (const hook of options.hooks.init) {\n hook(options);\n }\n\n let retryCount = 0;\n const startTime = typeof options.totalTimeout === 'number' ? performance.now() : undefined;\n /** @type {Request} */\n let currentRequest;\n\n const getRemainingTotalTimeout = () => {\n if (startTime === undefined) return undefined;\n const elapsed = performance.now() - startTime;\n return Math.max(0, options.totalTimeout - elapsed);\n };\n\n const getEffectiveTimeout = () => {\n const remaining = getRemainingTotalTimeout();\n if (options.timeout === false) return remaining;\n if (remaining === undefined) return options.timeout;\n return Math.min(options.timeout, remaining);\n };\n\n const throwIfTotalTimeoutExhausted = () => {\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) {\n throw new TimeoutError(currentRequest);\n }\n };\n\n const innerPromise = (async () => {\n if (typeof options.timeout === 'number' && options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n if (typeof options.totalTimeout === 'number' && options.totalTimeout > maxSafeTimeout) {\n throw new RangeError(`The \\`totalTimeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n\n // Resolve URL\n const inputStr = resolveInput(input, { prefix: options.prefix, baseUrl: options.baseUrl });\n let url = new URL(inputStr);\n url = appendSearchParams(url, options.searchParams);\n\n // Build request init (strip neta-specific options)\n const {\n prefix: _prefix, baseUrl: _baseUrl, retry, timeout, totalTimeout,\n hooks, searchParams, json, throwHttpErrors, fetch: fetchFn,\n parseJson, stringifyJson, context, _userSignal,\n onDownloadProgress, onUploadProgress,\n ...requestInit\n } = options;\n\n currentRequest = new Request(url.href, {\n ...requestInit,\n method: options.method.toUpperCase(),\n });\n\n // Defer so body shortcuts can set Accept header\n await Promise.resolve();\n\n // beforeRequest hooks\n for (const hook of hooks.beforeRequest) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n retryCount: 0,\n });\n\n if (result instanceof Response) return result;\n if (result instanceof Request) currentRequest = result;\n }\n\n const userSignal = options._userSignal;\n\n /**\n * Perform a single fetch attempt with timeout.\n * @returns {Promise<Response>}\n */\n const doFetch = async () => {\n const effectiveTimeout = getEffectiveTimeout();\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) throw new TimeoutError(currentRequest);\n\n const managed = createManagedSignal(effectiveTimeout, userSignal);\n\n let fetchRequest = currentRequest.clone();\n if (onUploadProgress && fetchRequest.body && supportsRequestStreams) {\n fetchRequest = streamRequest(fetchRequest, onUploadProgress, options.body);\n }\n\n try {\n const response = await fetchFn(fetchRequest, { signal: managed.signal });\n managed.cleanup();\n return response;\n } catch (error) {\n managed.cleanup();\n if (managed.signal.aborted && managed.signal.reason === 'timeout') {\n throw new TimeoutError(currentRequest);\n }\n if (isNetworkError(error)) {\n throw new NetworkError(currentRequest, { cause: error });\n }\n throw error;\n }\n };\n\n /**\n * Attempt retry: wait, run beforeRetry hooks, then fetch again.\n * @param {Error} error\n * @param {number} delayMs\n * @returns {Promise<Response | typeof stop>}\n */\n const attemptRetry = async (error, delayMs) => {\n const safeDelay = Math.min(delayMs, maxSafeTimeout);\n const delayOptions = { signal: userSignal };\n\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined) {\n if (remaining <= 0) throw new TimeoutError(currentRequest);\n if (safeDelay >= remaining) {\n await delay(remaining, delayOptions);\n throw new TimeoutError(currentRequest);\n }\n }\n\n await delay(safeDelay, delayOptions);\n throwIfTotalTimeoutExhausted();\n\n // Run beforeRetry hooks\n for (const hook of hooks.beforeRetry) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error,\n retryCount: retryCount + 1,\n });\n\n if (result instanceof Request) { currentRequest = result; break; }\n if (result instanceof Response) { retryCount++; return result; }\n if (result === stop) return stop;\n }\n\n throwIfTotalTimeoutExhausted();\n retryCount++;\n return doFetch();\n };\n\n /**\n * Check if we should retry a fetch-level error (timeout, network).\n * @param {Error} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForFetchError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof TimeoutError) {\n if (!retry.retryOnTimeout) throw error;\n return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof NetworkError) {\n return calculateDelay(retry, retryCount + 1);\n }\n\n throw error;\n };\n\n /**\n * Check if we should retry an HTTP error.\n * @param {HTTPError} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForHttpError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (!retry.statusCodes.includes(error.response.status)) throw error;\n\n // Handle Retry-After\n if (retry.afterStatusCodes.includes(error.response.status)) {\n const retryAfter = parseRetryAfter(error.response);\n if (retryAfter !== undefined) {\n return Math.min(retry.maxRetryAfter, Math.max(0, retryAfter));\n }\n }\n\n if (error.response.status === 413) throw error;\n\n return calculateDelay(retry, retryCount + 1);\n };\n\n // === Main request loop ===\n /** @type {Response} */\n let response;\n\n // Initial fetch with fetch-error retry loop\n for (;;) {\n try {\n response = await doFetch();\n break;\n } catch (error) {\n const retryDelay = await getRetryDelayForFetchError(error);\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) { response = retryResult; break; }\n }\n }\n\n // afterResponse hooks + HTTP error retry loop\n let responseFromHook = false;\n\n for (;;) {\n // Run afterResponse hooks\n try {\n for (const hook of hooks.afterResponse) {\n const clonedResponse = response.clone();\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n response: clonedResponse,\n retryCount,\n });\n\n if (hookResult instanceof RetryMarker) {\n throw new ForceRetryError(hookResult.options);\n }\n\n if (hookResult instanceof Response) {\n response = hookResult;\n }\n }\n } catch (error) {\n if (!(error instanceof ForceRetryError)) throw error;\n\n // Forced retry from afterResponse hook\n const retryDelay = error.customDelay ?? calculateDelay(retry, retryCount + 1);\n if (error.customRequest) currentRequest = error.customRequest;\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = true;\n continue;\n }\n continue;\n }\n\n // Check HTTP errors\n const shouldThrow = typeof throwHttpErrors === 'function'\n ? throwHttpErrors(response.status)\n : throwHttpErrors;\n\n if (!response.ok && response.type !== 'opaque' && shouldThrow) {\n const error = new HTTPError(response, currentRequest, getNormalizedOptions(options));\n error.data = await getResponseData(\n response,\n options.timeout === false ? 10_000 : options.timeout,\n options,\n currentRequest,\n );\n\n if (responseFromHook) throw error;\n\n // Try to retry\n let retryDelay;\n try {\n retryDelay = await getRetryDelayForHttpError(error);\n } catch {\n // Run beforeError hooks, then throw\n let processedError = error;\n for (const hook of hooks.beforeError) {\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error: processedError,\n retryCount,\n });\n if (hookResult instanceof Error) processedError = hookResult;\n }\n throw processedError;\n }\n\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = false; // Allow further retries\n continue;\n }\n continue;\n }\n\n break;\n }\n\n // Decorate response with custom parseJson\n if (options.parseJson) {\n response.json = async () => {\n const text = await response.clone().text();\n if (text === '') return JSON.parse(text);\n return options.parseJson(text, { request: currentRequest, response });\n };\n }\n\n // Handle download progress\n if (onDownloadProgress) {\n if (typeof onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported. `ReadableStream` is missing.');\n }\n return streamResponse(response, onDownloadProgress);\n }\n\n return response;\n })();\n\n // Build ResponsePromise thenable\n /** @type {any} */\n const responsePromise = {\n then: innerPromise.then.bind(innerPromise),\n catch: innerPromise.catch.bind(innerPromise),\n finally: innerPromise.finally.bind(innerPromise),\n [Symbol.toStringTag]: 'ResponsePromise',\n };\n\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n responsePromise[type] = async (schema) => {\n if (currentRequest) {\n currentRequest.headers.set('accept', currentRequest.headers.get('accept') || mimeType);\n }\n\n const response = await innerPromise;\n if (type !== 'json') return response[type]();\n\n const text = await response.text();\n if (text === '') {\n if (schema !== undefined) return validateJsonWithSchema(undefined, schema);\n return JSON.parse(text);\n }\n\n const jsonValue = options.parseJson\n ? await options.parseJson(text, { request: currentRequest, response })\n : JSON.parse(text);\n\n return schema === undefined ? jsonValue : validateJsonWithSchema(jsonValue, schema);\n };\n }\n\n return responsePromise;\n}\n","import { HTTP_METHODS } from './constants.js';\nimport { createResponsePromise } from './core.js';\nimport { RetryMarker } from './types.js';\nimport { mergeOptions, normalizeOptions } from './utils.js';\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @returns {import('../types/types.js').NetaInstance}\n */\nexport function createInstance(defaults) {\n const fn = (input, options) => {\n const merged = mergeOptions(defaults, options);\n const normalized = normalizeOptions(merged);\n // Stash user signal before we override it internally\n normalized._userSignal = normalized.signal ?? undefined;\n return createResponsePromise(input, normalized);\n };\n\n for (const method of HTTP_METHODS) {\n fn[method] = (input, options) => fn(input, { ...options, method });\n }\n\n fn.create = (newDefaults) => createInstance(mergeOptions(defaults, newDefaults));\n fn.extend = fn.create;\n\n /**\n * Signal forced retry from an afterResponse hook.\n * @param {{ delay?: number, request?: Request }} [options]\n * @returns {RetryMarker}\n */\n fn.retry = (options) => new RetryMarker(options);\n\n return fn;\n}\n\nconst neta = createInstance();\n\nexport default neta;\nexport { neta };\nexport { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nexport { HTTPError as NetaError } from './errors.js';\nexport { createInstance as NetaClient };\nexport { stop } from './types.js';\n"],"mappings":"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","names":["HTTP_METHODS","DEFAULT_RETRY","attemptCount","DEFAULT_TIMEOUT","maxSafeTimeout","responseTypes","supportsAbortController","supportsAbortSignal","supportsFormData","supportsResponseStreams","supportsRequestStreams","duplexAccessed","hasContentType","HTTPError","response","request","options","status","TimeoutError","NetworkError","ForceRetryError","SchemaValidationError","issues","message","i","stop","RetryMarker","options","streamResponse","response","onDownloadProgress","totalBytes","transferredBytes","reader","stream","controller","done","value","percent","reason","streamRequest","request","onUploadProgress","originalBody","normalizeRetry","retry","DEFAULT_RETRY","normalizeHooks","hooks","mergeHeaders","target","source","result","value","key","mergeHooks","base","override","mergeOptions","defaults","overrides","merged","resolveInput","input","options","inputStr","prefix","path","appendSearchParams","url","searchParams","cleaned","params","normalizeOptions","normalized","normalizeRequestMethod","DEFAULT_TIMEOUT","headers","method","delay","ms","resolve","reject","signal","timer","parseRetryAfter","response","header","seconds","date","applyJitter","delayMs","jitter","isNetworkError","error","invalidSchemaMessage","validateJsonWithSchema","jsonValue","schema","standardSchema","result","SchemaValidationError","createManagedSignal","timeout","userSignal","controller","timer","readResponseText","response","timeoutMs","body","reader","decoder","chunks","totalBytes","maxSize","readAll","done","value","timeoutPromise","resolve","id","getResponseData","options","request","text","contentType","getNormalizedOptions","hooks","json","parseJson","stringifyJson","searchParams","totalTimeout","throwHttpErrors","fetch","context","_userSignal","prefix","baseUrl","onDownloadProgress","onUploadProgress","rest","calculateDelay","retry","retryCount","base","jittered","applyJitter","createResponsePromise","input","hook","startTime","currentRequest","getRemainingTotalTimeout","elapsed","getEffectiveTimeout","remaining","throwIfTotalTimeoutExhausted","TimeoutError","innerPromise","maxSafeTimeout","inputStr","resolveInput","url","appendSearchParams","_prefix","_baseUrl","fetchFn","requestInit","doFetch","effectiveTimeout","managed","fetchRequest","supportsRequestStreams","streamRequest","error","isNetworkError","NetworkError","attemptRetry","delayMs","safeDelay","delayOptions","delay","stop","getRetryDelayForFetchError","getRetryDelayForHttpError","retryAfter","parseRetryAfter","retryDelay","retryResult","responseFromHook","clonedResponse","hookResult","RetryMarker","ForceRetryError","shouldThrow","HTTPError","processedError","supportsResponseStreams","streamResponse","responsePromise","type","mimeType","responseTypes","createInstance","defaults","fn","input","options","merged","mergeOptions","normalized","normalizeOptions","createResponsePromise","method","HTTP_METHODS","newDefaults","RetryMarker","neta","index_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.js","../src/errors.js","../src/types.js","../src/stream.js","../src/utils.js","../src/core.js","../src/index.js"],"sourcesContent":["/** @type {import('../types/types.js').HttpMethod[]} */\nexport const HTTP_METHODS = [\n 'get', 'post', 'put', 'patch', 'delete', 'head', 'options',\n];\n\n/** @type {import('../types/types.js').RetryOptions} */\nexport const DEFAULT_RETRY = {\n limit: 2,\n methods: ['get', 'put', 'head', 'delete', 'options'],\n statusCodes: [408, 413, 429, 500, 502, 503, 504],\n afterStatusCodes: [413, 429, 503],\n maxRetryAfter: Infinity,\n backoffLimit: Infinity,\n delay: (attemptCount) => 300 * 2 ** (attemptCount - 1),\n jitter: false,\n retryOnTimeout: false,\n shouldRetry: undefined,\n};\n\nexport const DEFAULT_TIMEOUT = 10_000;\n\nexport const maxSafeTimeout = 2_147_483_647; // 2^31 - 1\n\n/** @type {Record<string, string>} */\nexport const responseTypes = {\n json: 'application/json',\n text: 'text/*',\n formData: 'multipart/form-data',\n arrayBuffer: '*/*',\n blob: '*/*',\n bytes: '*/*',\n};\n\nexport const supportsAbortController = typeof globalThis.AbortController === 'function';\nexport const supportsAbortSignal = typeof globalThis.AbortSignal !== 'undefined';\nexport const supportsFormData = typeof globalThis.FormData === 'function';\n\nexport const supportsResponseStreams = (() => {\n try {\n return typeof globalThis.ReadableStream === 'function';\n } catch {\n return false;\n }\n})();\n\nexport const supportsRequestStreams = (() => {\n try {\n let duplexAccessed = false;\n const hasContentType = new Request(\n new URL('https://empty.invalid'),\n {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n },\n ).headers.has('Content-Type');\n return duplexAccessed && !hasContentType;\n } catch {\n return false;\n }\n})();\n","export class HTTPError extends Error {\n /**\n * @param {Response} response\n * @param {Request} request\n * @param {import('./types.js').NormalizedOptions} options\n */\n constructor(response, request, options) {\n const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ''}`;\n super(`Request failed with status code ${status}`);\n this.name = 'HTTPError';\n this.response = response;\n this.request = request;\n this.options = options;\n /** @type {unknown} */\n this.data = undefined;\n }\n}\n\nexport class TimeoutError extends Error {\n /**\n * @param {Request} request\n */\n constructor(request) {\n super('Request timed out');\n this.name = 'TimeoutError';\n this.request = request;\n }\n}\n\nexport class NetworkError extends Error {\n /**\n * @param {Request} request\n * @param {{ cause?: Error }} [options]\n */\n constructor(request, options) {\n super('Network error', options);\n this.name = 'NetworkError';\n this.request = request;\n }\n}\n\nexport class ForceRetryError extends Error {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n super('Force retry');\n this.name = 'ForceRetryError';\n this.customDelay = options?.delay;\n this.customRequest = options?.request;\n }\n}\n\nexport class SchemaValidationError extends Error {\n /**\n * @param {Array<{ message?: string, path?: Array<string | number | symbol> }>} issues\n */\n constructor(issues) {\n const message = issues.map((i) => i.message ?? 'Unknown validation error').join('; ');\n super(`Schema validation failed: ${message}`);\n this.name = 'SchemaValidationError';\n this.issues = issues;\n }\n}\n","/** @type {unique symbol} */\nexport const stop = Symbol('neta.stop');\n\nexport class RetryMarker {\n /**\n * @param {{ delay?: number, request?: Request }} [options]\n */\n constructor(options) {\n this.options = options;\n }\n}\n","/**\n * @param {Response} response\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onDownloadProgress\n * @returns {Response}\n */\nexport function streamResponse(response, onDownloadProgress) {\n const totalBytes = Number(response.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = response.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onDownloadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onDownloadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n}\n\n/**\n * @param {Request} request\n * @param {(progress: { percent: number, transferredBytes: number, totalBytes: number }) => void} onUploadProgress\n * @param {BodyInit} [originalBody]\n * @returns {Request}\n */\nexport function streamRequest(request, onUploadProgress, originalBody) {\n const totalBytes = Number(request.headers.get('content-length')) || 0;\n let transferredBytes = 0;\n\n const reader = request.body.getReader();\n\n const stream = new ReadableStream({\n async pull(controller) {\n const { done, value } = await reader.read();\n if (done) {\n onUploadProgress({\n percent: 1,\n transferredBytes,\n totalBytes: totalBytes || transferredBytes,\n });\n controller.close();\n return;\n }\n\n transferredBytes += value.byteLength;\n const percent = totalBytes ? transferredBytes / totalBytes : 0;\n onUploadProgress({ percent, transferredBytes, totalBytes });\n controller.enqueue(value);\n },\n cancel(reason) {\n return reader.cancel(reason);\n },\n });\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n duplex: 'half',\n signal: request.signal,\n });\n}\n","import { DEFAULT_RETRY, DEFAULT_TIMEOUT } from './constants.js';\n\n/**\n * @param {import('../types/types.js').Options['retry']} retry\n * @returns {import('../types/types.js').RetryOptions}\n */\nexport function normalizeRetry(retry) {\n if (typeof retry === 'number') {\n return { ...DEFAULT_RETRY, limit: retry };\n }\n return { ...DEFAULT_RETRY, ...retry };\n}\n\n/**\n * @param {import('../types/types.js').Hooks} [hooks]\n * @returns {import('../types/types.js').NormalizedHooks}\n */\nexport function normalizeHooks(hooks) {\n return {\n init: [...(hooks?.init ?? [])],\n beforeRequest: [...(hooks?.beforeRequest ?? [])],\n afterResponse: [...(hooks?.afterResponse ?? [])],\n beforeError: [...(hooks?.beforeError ?? [])],\n beforeRetry: [...(hooks?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {HeadersInit} [target]\n * @param {HeadersInit} [source]\n * @returns {Headers}\n */\nexport function mergeHeaders(target, source) {\n const result = new Headers(target);\n if (source) {\n const sourceHeaders = new Headers(source);\n sourceHeaders.forEach((value, key) => {\n result.set(key, value);\n });\n }\n return result;\n}\n\n/**\n * Merge hooks by concatenating arrays.\n * @param {import('../types/types.js').Hooks} [base]\n * @param {import('../types/types.js').Hooks} [override]\n * @returns {import('../types/types.js').Hooks}\n */\nexport function mergeHooks(base, override) {\n return {\n init: [...(base?.init ?? []), ...(override?.init ?? [])],\n beforeRequest: [...(base?.beforeRequest ?? []), ...(override?.beforeRequest ?? [])],\n afterResponse: [...(base?.afterResponse ?? []), ...(override?.afterResponse ?? [])],\n beforeError: [...(base?.beforeError ?? []), ...(override?.beforeError ?? [])],\n beforeRetry: [...(base?.beforeRetry ?? []), ...(override?.beforeRetry ?? [])],\n };\n}\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @param {import('../types/types.js').Options} [overrides]\n * @returns {import('../types/types.js').Options}\n */\nexport function mergeOptions(defaults, overrides) {\n if (!defaults) return overrides ?? {};\n if (!overrides) return defaults;\n\n const merged = { ...defaults, ...overrides };\n\n if (defaults.headers || overrides.headers) {\n merged.headers = mergeHeaders(defaults.headers, overrides.headers);\n }\n\n if (defaults.hooks || overrides.hooks) {\n merged.hooks = mergeHooks(defaults.hooks, overrides.hooks);\n }\n\n return merged;\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {{ prefix?: string, baseUrl?: string | URL }} [options]\n * @returns {string}\n */\nexport function resolveInput(input, options) {\n let inputStr = input instanceof Request ? input.url : String(input);\n\n if (options?.prefix) {\n const prefix = String(options.prefix).replace(/\\/+$/, '');\n const path = inputStr.replace(/^\\/+/, '');\n inputStr = `${prefix}/${path}`;\n }\n\n if (options?.baseUrl) {\n try {\n // If already absolute, keep as-is\n new URL(inputStr);\n } catch {\n // Relative — resolve against baseUrl\n inputStr = new URL(inputStr, new Request(String(options.baseUrl)).url).href;\n }\n }\n\n return inputStr;\n}\n\n/**\n * @param {URL} url\n * @param {import('../types/types.js').SearchParamsInit} [searchParams]\n * @returns {URL}\n */\nexport function appendSearchParams(url, searchParams) {\n if (!searchParams) return url;\n\n if (typeof searchParams === 'string') {\n const cleaned = searchParams.replace(/^\\?/, '');\n if (cleaned) {\n url.search = url.search ? `${url.search}&${cleaned}` : `?${cleaned}`;\n }\n return url;\n }\n\n /** @type {URLSearchParams} */\n let params;\n\n if (searchParams instanceof URLSearchParams) {\n params = searchParams;\n } else if (Array.isArray(searchParams)) {\n params = new URLSearchParams(searchParams);\n } else {\n params = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value !== undefined) {\n params.set(key, String(value));\n }\n }\n }\n\n params.forEach((value, key) => {\n url.searchParams.append(key, value);\n });\n\n return url;\n}\n\n/**\n * @param {import('../types/types.js').Options} options\n * @returns {import('../types/types.js').InternalOptions}\n */\nexport function normalizeOptions(options) {\n const normalized = {\n ...options,\n method: normalizeRequestMethod(options.method ?? 'get'),\n retry: normalizeRetry(options.retry),\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n totalTimeout: options.totalTimeout ?? false,\n hooks: normalizeHooks(options.hooks),\n throwHttpErrors: options.throwHttpErrors ?? true,\n fetch: options.fetch ?? globalThis.fetch.bind(globalThis),\n context: options.context ?? {},\n prefix: options.prefix ? String(options.prefix) : '',\n };\n\n if (options.bearerToken !== undefined) {\n const headers = new Headers(normalized.headers);\n if (!headers.has('authorization')) {\n headers.set('authorization', `Bearer ${options.bearerToken}`);\n }\n normalized.headers = headers;\n }\n\n if (options.json !== undefined) {\n normalized.body = normalized.stringifyJson\n ? normalized.stringifyJson(options.json)\n : JSON.stringify(options.json);\n const headers = new Headers(normalized.headers);\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json');\n }\n normalized.headers = headers;\n }\n\n return normalized;\n}\n\n/**\n * @param {string} [method]\n * @returns {string}\n */\nexport function normalizeRequestMethod(method) {\n return (method ?? 'get').toLowerCase();\n}\n\n/**\n * @param {number} ms\n * @param {{ signal?: AbortSignal }} [options]\n * @returns {Promise<void>}\n */\nexport function delay(ms, options) {\n return new Promise((resolve, reject) => {\n const signal = options?.signal;\n\n if (signal?.aborted) {\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n return;\n }\n\n const timer = setTimeout(resolve, ms);\n\n if (signal) {\n signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n },\n { once: true },\n );\n }\n });\n}\n\n/**\n * Parse Retry-After from multiple common header formats.\n * @param {Response} response\n * @returns {number | undefined}\n */\nexport function parseRetryAfter(response) {\n const header =\n response.headers.get('retry-after') ??\n response.headers.get('ratelimit-reset') ??\n response.headers.get('x-ratelimit-retry-after') ??\n response.headers.get('x-ratelimit-reset') ??\n response.headers.get('x-rate-limit-reset');\n\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) {\n // Large numbers are treated as timestamps (threshold: 2024-01-01 epoch)\n if (seconds >= Date.parse('2024-01-01') / 1000) {\n return Math.max(0, seconds * 1000 - Date.now());\n }\n return seconds * 1000;\n }\n\n const date = Date.parse(header);\n if (!Number.isNaN(date)) {\n return Math.max(0, date - Date.now());\n }\n\n return undefined;\n}\n\n/**\n * Apply jitter to a delay value.\n * @param {number} delayMs\n * @param {boolean | ((delay: number) => number)} jitter\n * @returns {number}\n */\nexport function applyJitter(delayMs, jitter) {\n if (jitter === true) {\n return Math.random() * delayMs;\n }\n if (typeof jitter === 'function') {\n const result = jitter(delayMs);\n return Number.isFinite(result) && result >= 0 ? result : delayMs;\n }\n return delayMs;\n}\n\n/**\n * Check if error is a raw network error (TypeError from fetch).\n * @param {unknown} error\n * @returns {boolean}\n */\nexport function isNetworkError(error) {\n return (\n error instanceof TypeError &&\n (error.message === 'Failed to fetch' ||\n error.message === 'fetch failed' ||\n error.message === 'NetworkError when attempting to fetch resource.' ||\n error.message.includes('network') ||\n error.message.includes('ECONNREFUSED') ||\n error.message.includes('ENOTFOUND') ||\n error.message.includes('ETIMEDOUT') ||\n error.message.includes('ECONNRESET'))\n );\n}\n","import { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nimport { RetryMarker } from './types.js';\nimport { stop } from './types.js';\nimport { streamResponse, streamRequest } from './stream.js';\nimport {\n appendSearchParams,\n resolveInput,\n delay,\n isNetworkError,\n applyJitter,\n parseRetryAfter,\n} from './utils.js';\nimport {\n maxSafeTimeout,\n responseTypes,\n supportsResponseStreams,\n supportsRequestStreams,\n} from './constants.js';\n\nconst invalidSchemaMessage = 'The `schema` argument must follow the Standard Schema specification';\n\n/**\n * @param {unknown} jsonValue\n * @param {any} schema\n * @returns {Promise<unknown>}\n */\nasync function validateJsonWithSchema(jsonValue, schema) {\n if ((typeof schema !== 'object' && typeof schema !== 'function') || schema === null) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const standardSchema = schema['~standard'];\n if (\n typeof standardSchema !== 'object' ||\n standardSchema === null ||\n typeof standardSchema.validate !== 'function'\n ) {\n throw new TypeError(invalidSchemaMessage);\n }\n\n const result = await standardSchema.validate(jsonValue);\n if (result.issues) {\n throw new SchemaValidationError(result.issues);\n }\n\n return result.value;\n}\n\n/**\n * @param {number | false} timeout\n * @param {AbortSignal} [userSignal]\n * @returns {{ signal: AbortSignal, cleanup: () => void }}\n */\nfunction createManagedSignal(timeout, userSignal) {\n const controller = new AbortController();\n /** @type {ReturnType<typeof setTimeout> | undefined} */\n let timer;\n\n if (timeout !== false && typeof timeout === 'number') {\n timer = setTimeout(() => controller.abort('timeout'), timeout);\n }\n\n if (userSignal) {\n if (userSignal.aborted) {\n controller.abort(userSignal.reason);\n } else {\n userSignal.addEventListener('abort', () => controller.abort(userSignal.reason), { once: true });\n }\n }\n\n return {\n signal: controller.signal,\n cleanup: () => {\n if (timer) clearTimeout(timer);\n },\n };\n}\n\n/**\n * Read response text with timeout and size limit.\n * @param {Response} response\n * @param {number} timeoutMs\n * @returns {Promise<string | undefined>}\n */\nasync function readResponseText(response, timeoutMs) {\n const { body } = response;\n if (!body) {\n try {\n return await response.text();\n } catch {\n return undefined;\n }\n }\n\n /** @type {ReadableStreamDefaultReader<Uint8Array>} */\n let reader;\n try {\n reader = body.getReader();\n } catch {\n return undefined;\n }\n\n const decoder = new TextDecoder();\n const chunks = [];\n let totalBytes = 0;\n const maxSize = 10 * 1024 * 1024;\n\n const readAll = (async () => {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n totalBytes += value.byteLength;\n if (totalBytes > maxSize) {\n void reader.cancel().catch(() => {});\n return undefined;\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n } catch {\n return undefined;\n }\n chunks.push(decoder.decode());\n return chunks.join('');\n })();\n\n const timeoutPromise = new Promise((resolve) => {\n const id = setTimeout(() => resolve(undefined), timeoutMs);\n void readAll.finally(() => clearTimeout(id));\n });\n\n const result = await Promise.race([readAll, timeoutPromise]);\n if (result === undefined) void reader.cancel().catch(() => {});\n return result;\n}\n\n/**\n * @param {Response} response\n * @param {number} timeoutMs\n * @param {any} options\n * @param {Request} request\n * @returns {Promise<unknown>}\n */\nasync function getResponseData(response, timeoutMs, options, request) {\n const text = await readResponseText(response, timeoutMs);\n if (!text) return undefined;\n\n const contentType = (response.headers.get('content-type') ?? '').split(';', 1)[0].trim().toLowerCase();\n const isJson = /\\/(?:.*[.+-])?json$/.test(contentType);\n if (!isJson) return text;\n\n try {\n return options.parseJson\n ? await options.parseJson(text, { request, response })\n : JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Strip internal-only options.\n * @param {any} options\n * @returns {any}\n */\nfunction getNormalizedOptions(options) {\n const {\n hooks, json, parseJson, stringifyJson, searchParams,\n timeout, totalTimeout, throwHttpErrors, fetch,\n context, _userSignal, prefix, baseUrl,\n onDownloadProgress, onUploadProgress, bearerToken,\n ...rest\n } = options;\n return Object.freeze(rest);\n}\n\n/**\n * Calculate retry delay.\n * @param {any} retry\n * @param {number} retryCount\n * @returns {number}\n */\nfunction calculateDelay(retry, retryCount) {\n const base = retry.delay(retryCount);\n const jittered = applyJitter(base, retry.jitter);\n return Math.min(retry.backoffLimit, jittered);\n}\n\n/**\n * @param {string | URL | Request} input\n * @param {any} options\n * @returns {any}\n */\nexport function createResponsePromise(input, options) {\n // Run init hooks (synchronous, mutate options clone)\n for (const hook of options.hooks.init) {\n hook(options);\n }\n\n let retryCount = 0;\n const startTime = typeof options.totalTimeout === 'number' ? performance.now() : undefined;\n /** @type {Request} */\n let currentRequest;\n\n const getRemainingTotalTimeout = () => {\n if (startTime === undefined) return undefined;\n const elapsed = performance.now() - startTime;\n return Math.max(0, options.totalTimeout - elapsed);\n };\n\n const getEffectiveTimeout = () => {\n const remaining = getRemainingTotalTimeout();\n if (options.timeout === false) return remaining;\n if (remaining === undefined) return options.timeout;\n return Math.min(options.timeout, remaining);\n };\n\n const throwIfTotalTimeoutExhausted = () => {\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) {\n throw new TimeoutError(currentRequest);\n }\n };\n\n const innerPromise = (async () => {\n if (typeof options.timeout === 'number' && options.timeout > maxSafeTimeout) {\n throw new RangeError(`The \\`timeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n if (typeof options.totalTimeout === 'number' && options.totalTimeout > maxSafeTimeout) {\n throw new RangeError(`The \\`totalTimeout\\` option cannot be greater than ${maxSafeTimeout}`);\n }\n\n // Resolve URL\n const inputStr = resolveInput(input, { prefix: options.prefix, baseUrl: options.baseUrl });\n let url = new URL(inputStr);\n url = appendSearchParams(url, options.searchParams);\n\n // Build request init (strip neta-specific options)\n const {\n prefix: _prefix, baseUrl: _baseUrl, retry, timeout, totalTimeout,\n hooks, searchParams, json, throwHttpErrors, fetch: fetchFn,\n parseJson, stringifyJson, context, _userSignal,\n onDownloadProgress, onUploadProgress, bearerToken: _bearerToken,\n ...requestInit\n } = options;\n\n currentRequest = new Request(url.href, {\n ...requestInit,\n method: options.method.toUpperCase(),\n });\n\n // Defer so body shortcuts can set Accept header\n await Promise.resolve();\n\n // beforeRequest hooks\n for (const hook of hooks.beforeRequest) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n retryCount: 0,\n });\n\n if (result instanceof Response) return result;\n if (result instanceof Request) currentRequest = result;\n }\n\n const userSignal = options._userSignal;\n\n /**\n * Perform a single fetch attempt with timeout.\n * @returns {Promise<Response>}\n */\n const doFetch = async () => {\n const effectiveTimeout = getEffectiveTimeout();\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined && remaining <= 0) throw new TimeoutError(currentRequest);\n\n const managed = createManagedSignal(effectiveTimeout, userSignal);\n\n let fetchRequest = currentRequest.clone();\n if (onUploadProgress && fetchRequest.body && supportsRequestStreams) {\n fetchRequest = streamRequest(fetchRequest, onUploadProgress, options.body);\n }\n\n try {\n const response = await fetchFn(fetchRequest, { signal: managed.signal });\n managed.cleanup();\n return response;\n } catch (error) {\n managed.cleanup();\n if (managed.signal.aborted && managed.signal.reason === 'timeout') {\n throw new TimeoutError(currentRequest);\n }\n if (isNetworkError(error)) {\n throw new NetworkError(currentRequest, { cause: error });\n }\n throw error;\n }\n };\n\n /**\n * Attempt retry: wait, run beforeRetry hooks, then fetch again.\n * @param {Error} error\n * @param {number} delayMs\n * @returns {Promise<Response | typeof stop>}\n */\n const attemptRetry = async (error, delayMs) => {\n const safeDelay = Math.min(delayMs, maxSafeTimeout);\n const delayOptions = { signal: userSignal };\n\n const remaining = getRemainingTotalTimeout();\n if (remaining !== undefined) {\n if (remaining <= 0) throw new TimeoutError(currentRequest);\n if (safeDelay >= remaining) {\n await delay(remaining, delayOptions);\n throw new TimeoutError(currentRequest);\n }\n }\n\n await delay(safeDelay, delayOptions);\n throwIfTotalTimeoutExhausted();\n\n // Run beforeRetry hooks\n for (const hook of hooks.beforeRetry) {\n const result = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error,\n retryCount: retryCount + 1,\n });\n\n if (result instanceof Request) { currentRequest = result; break; }\n if (result instanceof Response) { retryCount++; return result; }\n if (result === stop) return stop;\n }\n\n throwIfTotalTimeoutExhausted();\n retryCount++;\n return doFetch();\n };\n\n /**\n * Check if we should retry a fetch-level error (timeout, network).\n * @param {Error} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForFetchError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof TimeoutError) {\n if (!retry.retryOnTimeout) throw error;\n return calculateDelay(retry, retryCount + 1);\n }\n\n if (error instanceof NetworkError) {\n return calculateDelay(retry, retryCount + 1);\n }\n\n throw error;\n };\n\n /**\n * Check if we should retry an HTTP error.\n * @param {HTTPError} error\n * @returns {Promise<number>} delay in ms, or throws if no retry\n */\n const getRetryDelayForHttpError = async (error) => {\n if (retryCount >= retry.limit) throw error;\n if (!retry.methods.includes(options.method)) throw error;\n\n if (retry.shouldRetry !== undefined) {\n const result = await retry.shouldRetry({ error, retryCount: retryCount + 1 });\n if (result === false) throw error;\n if (result === true) return calculateDelay(retry, retryCount + 1);\n }\n\n if (!retry.statusCodes.includes(error.response.status)) throw error;\n\n // Handle Retry-After\n if (retry.afterStatusCodes.includes(error.response.status)) {\n const retryAfter = parseRetryAfter(error.response);\n if (retryAfter !== undefined) {\n return Math.min(retry.maxRetryAfter, Math.max(0, retryAfter));\n }\n }\n\n if (error.response.status === 413) throw error;\n\n return calculateDelay(retry, retryCount + 1);\n };\n\n // === Main request loop ===\n /** @type {Response} */\n let response;\n\n // Initial fetch with fetch-error retry loop\n for (;;) {\n try {\n response = await doFetch();\n break;\n } catch (error) {\n const retryDelay = await getRetryDelayForFetchError(error);\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) { response = retryResult; break; }\n }\n }\n\n // afterResponse hooks + HTTP error retry loop\n let responseFromHook = false;\n\n for (;;) {\n // Run afterResponse hooks\n try {\n for (const hook of hooks.afterResponse) {\n const clonedResponse = response.clone();\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n response: clonedResponse,\n retryCount,\n });\n\n if (hookResult instanceof RetryMarker) {\n throw new ForceRetryError(hookResult.options);\n }\n\n if (hookResult instanceof Response) {\n response = hookResult;\n }\n }\n } catch (error) {\n if (!(error instanceof ForceRetryError)) throw error;\n\n // Forced retry from afterResponse hook\n const retryDelay = error.customDelay ?? calculateDelay(retry, retryCount + 1);\n if (error.customRequest) currentRequest = error.customRequest;\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = true;\n continue;\n }\n continue;\n }\n\n // Check HTTP errors\n const shouldThrow = typeof throwHttpErrors === 'function'\n ? throwHttpErrors(response.status)\n : throwHttpErrors;\n\n if (!response.ok && response.type !== 'opaque' && shouldThrow) {\n const error = new HTTPError(response, currentRequest, getNormalizedOptions(options));\n error.data = await getResponseData(\n response,\n options.timeout === false ? 10_000 : options.timeout,\n options,\n currentRequest,\n );\n\n if (responseFromHook) throw error;\n\n // Try to retry\n let retryDelay;\n try {\n retryDelay = await getRetryDelayForHttpError(error);\n } catch {\n // Run beforeError hooks, then throw\n let processedError = error;\n for (const hook of hooks.beforeError) {\n const hookResult = await hook({\n request: currentRequest,\n options: getNormalizedOptions(options),\n error: processedError,\n retryCount,\n });\n if (hookResult instanceof Error) processedError = hookResult;\n }\n throw processedError;\n }\n\n const retryResult = await attemptRetry(error, retryDelay);\n if (retryResult === stop) return undefined;\n if (retryResult instanceof Response) {\n response = retryResult;\n responseFromHook = false; // Allow further retries\n continue;\n }\n continue;\n }\n\n break;\n }\n\n // Decorate response with custom parseJson\n if (options.parseJson) {\n response.json = async () => {\n const text = await response.clone().text();\n if (text === '') return JSON.parse(text);\n return options.parseJson(text, { request: currentRequest, response });\n };\n }\n\n // Handle download progress\n if (onDownloadProgress) {\n if (typeof onDownloadProgress !== 'function') {\n throw new TypeError('The `onDownloadProgress` option must be a function');\n }\n if (!supportsResponseStreams) {\n throw new Error('Streams are not supported. `ReadableStream` is missing.');\n }\n return streamResponse(response, onDownloadProgress);\n }\n\n return response;\n })();\n\n // Build ResponsePromise thenable\n /** @type {any} */\n const responsePromise = {\n then: innerPromise.then.bind(innerPromise),\n catch: innerPromise.catch.bind(innerPromise),\n finally: innerPromise.finally.bind(innerPromise),\n [Symbol.toStringTag]: 'ResponsePromise',\n };\n\n for (const [type, mimeType] of Object.entries(responseTypes)) {\n responsePromise[type] = async (schema) => {\n if (currentRequest) {\n currentRequest.headers.set('accept', currentRequest.headers.get('accept') || mimeType);\n }\n\n const response = await innerPromise;\n if (type !== 'json') return response[type]();\n\n const text = await response.text();\n if (text === '') {\n if (schema !== undefined) return validateJsonWithSchema(undefined, schema);\n return JSON.parse(text);\n }\n\n const jsonValue = options.parseJson\n ? await options.parseJson(text, { request: currentRequest, response })\n : JSON.parse(text);\n\n return schema === undefined ? jsonValue : validateJsonWithSchema(jsonValue, schema);\n };\n }\n\n return responsePromise;\n}\n","import { HTTP_METHODS } from './constants.js';\nimport { createResponsePromise } from './core.js';\nimport { RetryMarker } from './types.js';\nimport { mergeOptions, normalizeOptions } from './utils.js';\n\n/**\n * @param {import('../types/types.js').Options} [defaults]\n * @returns {import('../types/types.js').NetaInstance}\n */\nexport function createInstance(defaults) {\n const fn = (input, options) => {\n const merged = mergeOptions(defaults, options);\n const normalized = normalizeOptions(merged);\n // Stash user signal before we override it internally\n normalized._userSignal = normalized.signal ?? undefined;\n return createResponsePromise(input, normalized);\n };\n\n for (const method of HTTP_METHODS) {\n fn[method] = (input, options) => fn(input, { ...options, method });\n }\n\n fn.create = (newDefaults) => createInstance(mergeOptions(defaults, newDefaults));\n fn.extend = fn.create;\n\n /**\n * Signal forced retry from an afterResponse hook.\n * @param {{ delay?: number, request?: Request }} [options]\n * @returns {RetryMarker}\n */\n fn.retry = (options) => new RetryMarker(options);\n\n return fn;\n}\n\nconst neta = createInstance();\n\nexport default neta;\nexport { neta };\nexport { HTTPError, TimeoutError, NetworkError, ForceRetryError, SchemaValidationError } from './errors.js';\nexport { HTTPError as NetaError } from './errors.js';\nexport { createInstance as NetaClient };\nexport { stop } from './types.js';\n"],"mappings":"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","names":["HTTP_METHODS","DEFAULT_RETRY","attemptCount","DEFAULT_TIMEOUT","maxSafeTimeout","responseTypes","supportsAbortController","supportsAbortSignal","supportsFormData","supportsResponseStreams","supportsRequestStreams","duplexAccessed","hasContentType","HTTPError","response","request","options","status","TimeoutError","NetworkError","ForceRetryError","SchemaValidationError","issues","message","i","stop","RetryMarker","options","streamResponse","response","onDownloadProgress","totalBytes","transferredBytes","reader","stream","controller","done","value","percent","reason","streamRequest","request","onUploadProgress","originalBody","normalizeRetry","retry","DEFAULT_RETRY","normalizeHooks","hooks","mergeHeaders","target","source","result","value","key","mergeHooks","base","override","mergeOptions","defaults","overrides","merged","resolveInput","input","options","inputStr","prefix","path","appendSearchParams","url","searchParams","cleaned","params","normalizeOptions","normalized","normalizeRequestMethod","DEFAULT_TIMEOUT","headers","method","delay","ms","resolve","reject","signal","timer","parseRetryAfter","response","header","seconds","date","applyJitter","delayMs","jitter","isNetworkError","error","invalidSchemaMessage","validateJsonWithSchema","jsonValue","schema","standardSchema","result","SchemaValidationError","createManagedSignal","timeout","userSignal","controller","timer","readResponseText","response","timeoutMs","body","reader","decoder","chunks","totalBytes","maxSize","readAll","done","value","timeoutPromise","resolve","id","getResponseData","options","request","text","contentType","getNormalizedOptions","hooks","json","parseJson","stringifyJson","searchParams","totalTimeout","throwHttpErrors","fetch","context","_userSignal","prefix","baseUrl","onDownloadProgress","onUploadProgress","bearerToken","rest","calculateDelay","retry","retryCount","base","jittered","applyJitter","createResponsePromise","input","hook","startTime","currentRequest","getRemainingTotalTimeout","elapsed","getEffectiveTimeout","remaining","throwIfTotalTimeoutExhausted","TimeoutError","innerPromise","maxSafeTimeout","inputStr","resolveInput","url","appendSearchParams","_prefix","_baseUrl","fetchFn","_bearerToken","requestInit","doFetch","effectiveTimeout","managed","fetchRequest","supportsRequestStreams","streamRequest","error","isNetworkError","NetworkError","attemptRetry","delayMs","safeDelay","delayOptions","delay","stop","getRetryDelayForFetchError","getRetryDelayForHttpError","retryAfter","parseRetryAfter","retryDelay","retryResult","responseFromHook","clonedResponse","hookResult","RetryMarker","ForceRetryError","shouldThrow","HTTPError","processedError","supportsResponseStreams","streamResponse","responsePromise","type","mimeType","responseTypes","createInstance","defaults","fn","input","options","merged","mergeOptions","normalized","normalizeOptions","createResponsePromise","method","HTTP_METHODS","newDefaults","RetryMarker","neta","index_default"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anmetric/neta",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Tiny, elegant HTTP client built on fetch for browser and Node.js",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/anmetrics/neta.git"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"exports": {
|
|
7
11
|
".": {
|
package/types/types.d.ts
CHANGED
|
@@ -107,6 +107,7 @@ export interface Options extends Omit<RequestInit, 'method'> {
|
|
|
107
107
|
stringifyJson?: (value: unknown) => string;
|
|
108
108
|
throwHttpErrors?: boolean | ((status: number) => boolean);
|
|
109
109
|
fetch?: typeof globalThis.fetch;
|
|
110
|
+
bearerToken?: string;
|
|
110
111
|
context?: Record<string, unknown>;
|
|
111
112
|
onDownloadProgress?: (progress: DownloadProgress) => void;
|
|
112
113
|
onUploadProgress?: (progress: UploadProgress) => void;
|