1000fetches 0.1.5 → 0.1.7

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/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class e extends Error{name="HttpError";status;statusText;data;response;url;method;cause;constructor(e,t,r,a,s,n,o,i){super(`HTTP ${t} ${r}: ${e} (${o} ${n})`,{cause:i}),this.status=t,this.statusText=r,this.data=a,this.response=s,this.url=n,this.method=o}}class t extends Error{name="NetworkError";cause;constructor(e,t){super(e,{cause:t})}}class r extends Error{name="SchemaValidationError";schema;data;cause;constructor(e,t,r,a){super(e,{cause:a}),this.schema=t,this.data=r}}class a extends Error{name="TimeoutError";cause;constructor(e,t){super(e,{cause:t})}}class s extends Error{name="PathParameterError";url;requiredParams;providedParams;cause;constructor(e,t,r,a,s){super(e,{cause:s}),this.url=t,this.requiredParams=r,this.providedParams=a}}class n extends Error{name="MiddlewareError";interceptorType;url;method;cause;constructor(e,t,r,a,s){super(e,{cause:s}),this.interceptorType=t,this.url=r,this.method=a}}class o extends Error{name="SerializationError";cause;constructor(e,t){super(e,{cause:t})}}class i extends Error{name="InvalidSchemaError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t}}class c extends Error{name="AsyncSchemaValidationError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t}}class d extends Error{name="InvalidBaseUrlError";baseUrl;cause;constructor(e,t,r){super(e,{cause:r}),this.baseUrl=t}}function u(e){return null!==e&&("object"==typeof e||"function"==typeof e)&&"~standard"in e&&"object"==typeof e["~standard"]&&null!==e["~standard"]&&"validate"in e["~standard"]&&"function"==typeof e["~standard"].validate&&"version"in e["~standard"]&&"number"==typeof e["~standard"].version&&"vendor"in e["~standard"]&&"string"==typeof e["~standard"].vendor}function l(){return{validate(e,t){if(!u(e))throw new i("Schema must implement the Standard Schema interface",e);const a=e["~standard"].validate(t);if(a instanceof Promise)throw new c("Async Standard Schema validation is not supported in this context",e);if(a.issues)throw new r(JSON.stringify(a.issues),e,t);return a.value},isSchema:e=>u(e)}}function h(e,t,r){let a=0;return new ReadableStream({async start(s){try{for(;;){const{done:n,value:o}=await e.read();if(n)break;a+=o.length,t(o,r,a),s.enqueue(o)}}finally{e.releaseLock(),s.close()}}})}async function f(e,t){if(!t||!e.body)return e;const r=h(e.body.getReader(),(e,r,a)=>{t({chunk:e,totalBytes:r,transferredBytes:a})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):0);return new Request(e.url,{method:e.method,headers:e.headers,body:r,signal:e.signal,credentials:e.credentials,cache:e.cache,mode:e.mode,redirect:e.redirect,referrer:e.referrer,referrerPolicy:e.referrerPolicy,integrity:e.integrity,keepalive:e.keepalive,duplex:"half"})}async function m(e,t){if(!t||!e.body)return e;const r=h(e.body.getReader(),(e,r,a)=>{t({chunk:e,totalBytes:r,transferredBytes:a})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0);return new Response(r,{status:e.status,statusText:e.statusText,headers:e.headers})}const p={maxRetries:3,retryDelay:300,backoffFactor:2,retryStatusCodes:[429,500,502,503,504],retryNetworkErrors:!0,maxRetryDelay:3e4,shouldRetry:()=>!0};function y(e={}){const{baseUrl:t="",headers:r={},timeout:o=3e4,schemaValidator:i=l(),onRequestMiddleware:c,onResponseMiddleware:d}=e;return async function(u,l={}){const{method:h="GET",headers:y={},params:S,pathParams:T,body:v,schema:R,timeout:P=o,signal:U,credentials:$,cache:k,mode:O,redirect:q,onUploadStreaming:A,onDownloadStreaming:B,validateStatus:L,responseType:M,retryOptions:j}=l;let H=function(e,t={}){return e.replace(/:([a-zA-Z0-9_]+)/g,(r,a)=>{if(void 0===t[a])throw new s(`Missing required path parameter: ${a}`,e,[a],Object.keys(t));return String(t[a])})}(u,T);t&&(H=new URL(H,t).toString());let C={url:H,method:h,params:S,headers:new Headers({...r,...y}),body:v,signal:U,fetchOptions:{credentials:$,cache:k,mode:O,redirect:q}};if(c)try{C=await c(C)}catch(F){throw new n(E("Request middleware failed",F),"request",C.url,C.method,F instanceof Error?F:void 0)}if(C.params){const e=new URL(C.url);Object.entries(C.params).forEach(([t,r])=>{null!=r&&e.searchParams.set(t,String(r))}),C.url=e.toString()}const D={method:C.method,headers:C.headers,...C.fetchOptions};if(void 0!==C.body&&["POST","PUT","PATCH"].includes(C.method)){const{body:e,contentType:t}=function(e){if("string"==typeof e||e instanceof FormData||e instanceof URLSearchParams||e instanceof ArrayBuffer||e instanceof Blob||e instanceof ReadableStream)return{body:e};if(null!=e)return{body:JSON.stringify(e),contentType:"application/json"};return{body:""}}(C.body);D.body=e,t&&C.headers.set("content-type",t),D.duplex="half"}const N={...p,...e.retryOptions,...j},V=N.maxRetries;let I;for(let e=0;e<=V;e+=1){const t=new AbortController,r=setTimeout(()=>t.abort(),P),s=C.signal?(()=>{if(C.signal&&C.signal.aborted)return C.signal;const e=new AbortController,a=()=>{clearTimeout(r),e.abort()};return C.signal?.addEventListener("abort",a),t.signal.addEventListener("abort",a),e.signal})():t.signal;try{const e=new Request(C.url,D),t=A?await f(e,A):e,r=await fetch(t.url,{method:t.method,headers:t.headers,body:t.body,signal:s,...C.fetchOptions,...t.body&&{duplex:"half"}}),a=B?await m(r,B):r,o=await w(a,{validateStatus:L,schema:R,responseType:M},h,C.url,i);if(d)try{return await d(o)}catch(F){throw new n(E("Response middleware failed",F),"response",C.url,h,F instanceof Error?F:void 0)}return o}catch(F){if(clearTimeout(r),I=F instanceof Error?F:new Error(String(F)),"AbortError"===I.name&&(I=new a(`Request timeout after ${P}ms`,I)),e<V&&await b(I,e,N)){const t=g(e,N);await x(t);continue}throw I}}throw I||new Error("Request failed")}}async function w(t,a,s,n,i){const c=Object.fromEntries(t.headers.entries()),d=a.validateStatus||(e=>e>=200&&e<300);let u;try{if("text"===a.responseType)u=await t.text();else if("blob"===a.responseType)u=await t.blob();else if("arrayBuffer"===a.responseType)u=await t.arrayBuffer();else{const e=t.headers.get("content-type");u=e?.includes("application/json")?await t.json():e?.includes("text/")?await t.text():await t.arrayBuffer()}}catch(h){throw new o(E("Failed to parse response body",h),h instanceof Error?h:void 0)}if(!d(t.status))throw new e(`HTTP ${t.status} ${t.statusText}`,t.status,t.statusText,u,t,n,s);const l={data:u,status:t.status,statusText:t.statusText,headers:c,method:s,url:n,raw:t};if(a.schema)try{l.data=i.validate(a.schema,l.data)}catch(h){throw new r(`Schema validation failed: ${h instanceof Error?h.message:String(h)}`,a.schema,l.data,h instanceof Error?h:void 0)}return l}async function b(r,a,s){return!!s&&(s.shouldRetry?await s.shouldRetry(r,a):r instanceof e?s.retryStatusCodes?.includes(r.status)??!1:(r instanceof t||"TypeError"===r.name)&&(s.retryNetworkErrors??!1))}function g(e,t){if(!t)return 0;const r=t.retryDelay??300,a=t.backoffFactor??2,s=t.maxRetryDelay??3e4,n=r*Math.pow(a,e);return Math.min(n,s)}function E(e,t){return`${e}: ${t instanceof Error?t.message:String(t)}`}function x(e){return new Promise(t=>setTimeout(t,e))}function S(e){const t="undefined"!=typeof window&&void 0!==window.location&&"null"!==window.location.origin;if(!e)return t?window.location.origin:"";if(e.startsWith("/"))return t?new URL(e,window.location.origin).href.replace(/\/$/,""):e.replace(/\/$/,"");try{new URL(e)}catch{throw new d(`Invalid baseUrl: "${e}". Must be a valid absolute URL or relative path starting with "/".`,e)}return e.endsWith("/")?e.slice(0,-1):e}function T(e){const t=e;return t.data=async()=>(await e).data,t}function v(e={}){const t=y({...e,baseUrl:S(e.baseUrl)});return{get:function(e,...r){return T(t(e,{...r[0],method:"GET"}))},post:(e,r,...a)=>T(t(e,{...a[0],method:"POST",body:r})),put:(e,r,...a)=>T(t(e,{...a[0],method:"PUT",body:r})),patch:(e,r,...a)=>T(t(e,{...a[0],method:"PATCH",body:r})),delete:(e,...r)=>T(t(e,{...r[0],method:"DELETE"})),request:(e,r)=>T(t(e,r))}}const R=v();exports.AsyncSchemaValidationError=c,exports.HttpError=e,exports.MiddlewareError=n,exports.NetworkError=t,exports.PathParameterError=s,exports.SchemaValidationError=r,exports.SerializationError=o,exports.TimeoutError=a,exports.createHttpClient=v,exports.createSchemaValidator=l,exports.default=R,exports.http=R;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class e extends Error{name="HttpError";status;statusText;data;response;url;method;cause;constructor(e,t,r,a,s,n,o,i){super(`HTTP ${t} ${r}: ${e} (${o} ${n})`,{cause:i}),this.status=t,this.statusText=r,this.data=a,this.response=s,this.url=n,this.method=o}}class t extends Error{name="NetworkError";cause;constructor(e,t){super(e,{cause:t})}}class r extends Error{name="SchemaValidationError";schema;data;cause;constructor(e,t,r,a){super(e,{cause:a}),this.schema=t,this.data=r}}class a extends Error{name="TimeoutError";cause;constructor(e,t){super(e,{cause:t})}}class s extends Error{name="PathParameterError";url;requiredParams;providedParams;cause;constructor(e,t,r,a,s){super(e,{cause:s}),this.url=t,this.requiredParams=r,this.providedParams=a}}class n extends Error{name="MiddlewareError";interceptorType;url;method;cause;constructor(e,t,r,a,s){super(e,{cause:s}),this.interceptorType=t,this.url=r,this.method=a}}class o extends Error{name="SerializationError";cause;constructor(e,t){super(e,{cause:t})}}class i extends Error{name="InvalidSchemaError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t}}class c extends Error{name="AsyncSchemaValidationError";schema;cause;constructor(e,t,r){super(e,{cause:r}),this.schema=t}}class d extends Error{name="InvalidBaseUrlError";baseUrl;cause;constructor(e,t,r){super(e,{cause:r}),this.baseUrl=t}}function u(e){return null!==e&&("object"==typeof e||"function"==typeof e)&&"~standard"in e&&"object"==typeof e["~standard"]&&null!==e["~standard"]&&"validate"in e["~standard"]&&"function"==typeof e["~standard"].validate&&"version"in e["~standard"]&&"number"==typeof e["~standard"].version&&"vendor"in e["~standard"]&&"string"==typeof e["~standard"].vendor}function l(){return{validate(e,t){if(!u(e))throw new i("Schema must implement the Standard Schema interface",e);const a=e["~standard"].validate(t);if(a instanceof Promise)throw new c("Async Standard Schema validation is not supported in this context",e);if(a.issues)throw new r(JSON.stringify(a.issues),e,t);return a.value},isSchema:e=>u(e)}}function h(e,t,r){let a=0;return new ReadableStream({async start(s){try{for(;;){const{done:n,value:o}=await e.read();if(n)break;a+=o.length,t(o,r,a),s.enqueue(o)}}finally{e.releaseLock(),s.close()}}})}async function f(e,t){if(!t||!e.body)return e;const r=h(e.body.getReader(),(e,r,a)=>{t({chunk:e,totalBytes:r,transferredBytes:a})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):0);return new Request(e.url,{method:e.method,headers:e.headers,body:r,signal:e.signal,credentials:e.credentials,cache:e.cache,mode:e.mode,redirect:e.redirect,referrer:e.referrer,referrerPolicy:e.referrerPolicy,integrity:e.integrity,keepalive:e.keepalive,duplex:"half"})}async function m(e,t){if(!t||!e.body)return e;const r=h(e.body.getReader(),(e,r,a)=>{t({chunk:e,totalBytes:r,transferredBytes:a})},e.headers.get("content-length")?parseInt(e.headers.get("content-length")||"0",10):void 0);return new Response(r,{status:e.status,statusText:e.statusText,headers:e.headers})}const p={maxRetries:3,retryDelay:300,backoffFactor:2,retryStatusCodes:[429,500,502,503,504],retryNetworkErrors:!0,maxRetryDelay:3e4,shouldRetry:()=>!0};function y(e={}){const{baseUrl:t="",headers:r={},timeout:o=3e4,schemaValidator:i=l(),fetch:c=fetch,serializeBody:d,serializeParams:u,onRequestMiddleware:h,onResponseMiddleware:y}=e;return async function(l,T={}){const{method:v="GET",headers:R={},params:P,pathParams:U,body:O,schema:$,timeout:k=o,signal:q,credentials:A,cache:j,mode:B,redirect:L,onUploadStreaming:M,onDownloadStreaming:N,validateStatus:H,responseType:C,retryOptions:D}=T;let z=function(e,t={}){return e.replace(/:([a-zA-Z0-9_]+)/g,(r,a)=>{if(void 0===t[a])throw new s(`Missing required path parameter: ${a}`,e,[a],Object.keys(t));return String(t[a])})}(l,U);t&&(z=new URL(z,t).toString());let I={url:z,method:v,params:P,headers:new Headers({...r,...R}),body:O,signal:q,fetchOptions:{credentials:A,cache:j,mode:B,redirect:L}};if(h)try{I=await h(I)}catch(_){throw new n(x("Request middleware failed",_),"request",I.url,I.method,_ instanceof Error?_:void 0)}if(I.params){const e=new URL(I.url),t=u?u(I.params):new URLSearchParams(JSON.parse(JSON.stringify(I.params))).toString();if(t){const r=u&&t.startsWith("?")?t.slice(1):t;e.search=r}I.url=e.toString()}const J={method:I.method,headers:I.headers,...I.fetchOptions};if(void 0!==I.body&&("POST"===I.method||"PUT"===I.method||"PATCH"===I.method)){let e,t;if(d){const r=d(I.body);null==r?e="":(e=r,E(I.body)&&"string"==typeof r&&!I.headers.has("content-type")&&(t="application/json"))}else{const r=function(e){if("string"==typeof e||e instanceof FormData||e instanceof URLSearchParams||e instanceof ArrayBuffer||e instanceof Blob||e instanceof ReadableStream)return{body:e};if(E(e))return{body:JSON.stringify(e),contentType:"application/json"};return{body:e}}(I.body);e=r.body,t=r.contentType}J.body=e,t&&I.headers.set("content-type",t),J.duplex="half"}const V={...p,...e.retryOptions,...D},F=V.maxRetries;let W;for(let e=0;e<=F;e+=1){const t=new AbortController,r=setTimeout(()=>t.abort(),k),s=I.signal?(()=>{if(I.signal&&I.signal.aborted)return I.signal;const e=new AbortController,a=()=>{clearTimeout(r),e.abort()};return I.signal?.addEventListener("abort",a),t.signal.addEventListener("abort",a),e.signal})():t.signal;try{const e=new Request(I.url,J),t=M?await f(e,M):e,r=await c(t.url,{method:t.method,headers:t.headers,body:t.body,signal:s,...I.fetchOptions,...t.body&&{duplex:"half"}}),a=N?await m(r,N):r,o=await w(a,{validateStatus:H,schema:$,responseType:C},v,I.url,i);if(y)try{return await y(o)}catch(_){throw new n(x("Response middleware failed",_),"response",I.url,v,_ instanceof Error?_:void 0)}return o}catch(_){if(clearTimeout(r),W=_ instanceof Error?_:new Error(String(_)),"AbortError"===W.name&&(W=new a(`Request timeout after ${k}ms`,W)),e<F&&await b(W,e,V)){const t=g(e,V);await S(t);continue}throw W}}throw W||new Error("Request failed")}}async function w(t,a,s,n,i){const c=Object.fromEntries(t.headers.entries()),d=a.validateStatus||(e=>e>=200&&e<300);let u;try{if("text"===a.responseType)u=await t.text();else if("blob"===a.responseType)u=await t.blob();else if("arrayBuffer"===a.responseType)u=await t.arrayBuffer();else{const e=t.headers.get("content-type");u=e?.includes("application/json")?await t.json():e?.includes("text/")?await t.text():await t.arrayBuffer()}}catch(h){throw new o(x("Failed to parse response body",h),h instanceof Error?h:void 0)}if(!d(t.status))throw new e(`HTTP ${t.status} ${t.statusText}`,t.status,t.statusText,u,t,n,s);const l={data:u,status:t.status,statusText:t.statusText,headers:c,method:s,url:n,raw:t};if(a.schema)try{l.data=i.validate(a.schema,l.data)}catch(h){throw new r(`Schema validation failed: ${h instanceof Error?h.message:String(h)}`,a.schema,l.data,h instanceof Error?h:void 0)}return l}async function b(r,a,s){return!!s&&(s.shouldRetry?await s.shouldRetry(r,a):r instanceof e?s.retryStatusCodes?.includes(r.status)??!1:(r instanceof t||"TypeError"===r.name)&&(s.retryNetworkErrors??!1))}function g(e,t){if(!t)return 0;const r=t.retryDelay??300,a=t.backoffFactor??2,s=t.maxRetryDelay??3e4,n=r*Math.pow(a,e);return Math.min(n,s)}function E(e){return e&&"object"==typeof e&&"Object"===e.constructor?.name||Array.isArray(e)||"function"==typeof e?.toJSON}function x(e,t){return`${e}: ${t instanceof Error?t.message:String(t)}`}function S(e){return new Promise(t=>setTimeout(t,e))}function T(e){const t="undefined"!=typeof window&&void 0!==window.location&&"null"!==window.location.origin;if(!e)return t?window.location.origin:"";if(e.startsWith("/"))return t?new URL(e,window.location.origin).href.replace(/\/$/,""):e.replace(/\/$/,"");try{new URL(e)}catch{throw new d(`Invalid baseUrl: "${e}". Must be a valid absolute URL or relative path starting with "/".`,e)}return e.endsWith("/")?e.slice(0,-1):e}function v(e){const t=e;return t.data=async()=>(await e).data,t}function R(e={}){const t=y({...e,baseUrl:T(e.baseUrl)});return{get:function(e,...r){return v(t(e,{...r[0],method:"GET"}))},post:(e,r,...a)=>v(t(e,{...a[0],method:"POST",body:r})),put:(e,r,...a)=>v(t(e,{...a[0],method:"PUT",body:r})),patch:(e,r,...a)=>v(t(e,{...a[0],method:"PATCH",body:r})),delete:(e,...r)=>v(t(e,{...r[0],method:"DELETE"})),request:(e,r)=>v(t(e,r))}}const P=R();exports.AsyncSchemaValidationError=c,exports.HttpError=e,exports.MiddlewareError=n,exports.NetworkError=t,exports.PathParameterError=s,exports.SchemaValidationError=r,exports.SerializationError=o,exports.TimeoutError=a,exports.createHttpClient=R,exports.default=P,exports.http=P;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/errors.ts","../src/schema.ts","../src/utils/streaming.ts","../src/core.ts","../src/utils/path.ts","../src/client.ts"],"sourcesContent":["interface HttpClientError {\n name: string\n message: string\n cause?: Error\n stack?: string\n}\n\nexport class HttpError<TErrorData = unknown>\n extends Error\n implements HttpClientError\n{\n public readonly name = 'HttpError'\n public readonly status: number\n public readonly statusText: string\n public readonly data: TErrorData\n public readonly response: Response\n public readonly url: string\n public readonly method: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n data: TErrorData,\n response: Response,\n url: string,\n method: string,\n cause?: Error\n ) {\n const enhancedMessage = `HTTP ${status} ${statusText}: ${message} (${method} ${url})`\n super(enhancedMessage, { cause })\n this.status = status\n this.statusText = statusText\n this.data = data\n this.response = response\n this.url = url\n this.method = method\n }\n}\n\nexport class NetworkError extends Error implements HttpClientError {\n public readonly name = 'NetworkError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class SchemaValidationError extends Error implements HttpClientError {\n public readonly name = 'SchemaValidationError'\n public readonly schema: unknown\n public readonly data: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, data: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.data = data\n }\n}\n\nexport class TimeoutError extends Error implements HttpClientError {\n public readonly name = 'TimeoutError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class PathParameterError extends Error implements HttpClientError {\n public readonly name = 'PathParameterError'\n public readonly url: string\n public readonly requiredParams: string[]\n public readonly providedParams: string[]\n public override readonly cause?: Error\n\n constructor(\n message: string,\n url: string,\n requiredParams: string[],\n providedParams: string[],\n cause?: Error\n ) {\n super(message, { cause })\n this.url = url\n this.requiredParams = requiredParams\n this.providedParams = providedParams\n }\n}\n\nexport class MiddlewareError extends Error implements HttpClientError {\n public readonly name = 'MiddlewareError'\n public readonly interceptorType: 'request' | 'response'\n public readonly url?: string\n public readonly method?: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n interceptorType: 'request' | 'response',\n url?: string,\n method?: string,\n cause?: Error\n ) {\n super(message, { cause })\n this.interceptorType = interceptorType\n this.url = url\n this.method = method\n }\n}\n\nexport class SerializationError extends Error implements HttpClientError {\n public readonly name = 'SerializationError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class InvalidSchemaError extends Error implements HttpClientError {\n public readonly name = 'InvalidSchemaError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class AsyncSchemaValidationError\n extends Error\n implements HttpClientError\n{\n public readonly name = 'AsyncSchemaValidationError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class InvalidBaseUrlError extends Error implements HttpClientError {\n public readonly name = 'InvalidBaseUrlError'\n public readonly baseUrl: string\n public override readonly cause?: Error\n\n constructor(message: string, baseUrl: string, cause?: Error) {\n super(message, { cause })\n this.baseUrl = baseUrl\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport {\n AsyncSchemaValidationError,\n InvalidSchemaError,\n SchemaValidationError,\n} from './errors'\nimport { Schema } from './types'\n\n/**\n * Type guard to check if an object conforms to the Standard Schema V1 specification\n */\nfunction isStandardSchema(obj: unknown): obj is StandardSchemaV1 {\n return (\n obj !== null &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n '~standard' in obj &&\n typeof obj['~standard'] === 'object' &&\n obj['~standard'] !== null &&\n 'validate' in obj['~standard'] &&\n typeof obj['~standard'].validate === 'function' &&\n 'version' in obj['~standard'] &&\n typeof obj['~standard'].version === 'number' &&\n 'vendor' in obj['~standard'] &&\n typeof obj['~standard'].vendor === 'string'\n )\n}\n\n/**\n * Interface for schema validators that can validate data against schemas.\n *\n * This interface allows you to create custom schema validators that work\n * with different validation libraries (Zod, Valibot, Arktype, etc.).\n */\nexport interface SchemaValidator {\n /**\n * Validate data against a schema.\n *\n * @template T - The expected type after validation\n * @param schema - The schema to validate against\n * @param data - The data to validate\n * @returns The validated data with the correct type\n * @throws {SchemaValidationError} If the data doesn't match the schema\n */\n validate<T>(schema: Schema<T>, data: unknown): T\n\n /**\n * Check if an object is a valid schema.\n *\n * @param obj - The object to check\n * @returns True if the object is a valid schema, false otherwise\n */\n isSchema(obj: unknown): boolean\n}\n\n/**\n * Create a default schema validator that supports Standard Schema.\n *\n * This validator only works with schemas that implement the Standard Schema\n * interface. For full support of Zod, Valibot, and Arktype, use the\n * appropriate validator from their respective packages.\n *\n * @returns A schema validator instance\n *\n * @example\n * ```ts\n * import { createSchemaValidator } from '1000fetches'\n *\n * const validator = createSchemaValidator();\n *\n * // Use with HttpClient\n * const client = new HttpClient({\n * schemaValidator: validator\n * });\n * ```\n */\nexport function createSchemaValidator(): SchemaValidator {\n return {\n validate<T>(schema: Schema<T>, data: unknown): T {\n if (!isStandardSchema(schema)) {\n throw new InvalidSchemaError(\n 'Schema must implement the Standard Schema interface',\n schema\n )\n }\n\n const result = schema['~standard'].validate(data)\n\n if (result instanceof Promise) {\n throw new AsyncSchemaValidationError(\n 'Async Standard Schema validation is not supported in this context',\n schema\n )\n }\n\n if (result.issues) {\n throw new SchemaValidationError(\n JSON.stringify(result.issues),\n schema,\n data\n )\n }\n\n return result.value as T\n },\n\n isSchema(obj: unknown): boolean {\n return isStandardSchema(obj)\n },\n }\n}\n","import type { DownloadStreamingEvent, UploadStreamingEvent } from '../types'\n\nfunction createStreamingStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onChunk: (chunk: Uint8Array, totalBytes: number | undefined, transferredBytes: number) => void,\n totalBytes: number | undefined\n): ReadableStream<Uint8Array> {\n let transferredBytes = 0\n\n return new ReadableStream({\n async start(controller) {\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n transferredBytes += value.length\n onChunk(value, totalBytes, transferredBytes)\n controller.enqueue(value)\n }\n } finally {\n reader.releaseLock()\n controller.close()\n }\n },\n })\n}\n\n/**\n * Creates a request with upload streaming tracking\n */\nexport async function toStreamableRequest(\n request: Request,\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n): Promise<Request> {\n if (!onUploadStreaming || !request.body) {\n return request\n }\n\n const reader = request.body.getReader()\n const totalBytes = request.headers.get('content-length')\n ? parseInt(request.headers.get('content-length') || '0', 10)\n : 0\n\n const stream = createStreamingStream(reader, (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes: totalBytes as number, // Safe cast since we pass 0 as default\n transferredBytes,\n })\n }, totalBytes)\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n signal: request.signal,\n credentials: request.credentials,\n cache: request.cache,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n integrity: request.integrity,\n keepalive: request.keepalive,\n duplex: 'half',\n } as RequestInit)\n}\n\n/**\n * Creates a response with download streaming tracking\n */\nexport async function toStreamableResponse(\n response: Response,\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n): Promise<Response> {\n if (!onDownloadStreaming || !response.body) {\n return response\n }\n\n const reader = response.body.getReader()\n const totalBytes = response.headers.get('content-length')\n ? parseInt(response.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(reader, (chunk, totalBytes, transferredBytes) => {\n onDownloadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n }, totalBytes)\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n}\n","import {\n HttpError,\n MiddlewareError,\n NetworkError,\n SchemaValidationError,\n SerializationError,\n TimeoutError,\n} from './errors'\nimport { createSchemaValidator, type SchemaValidator } from './schema'\nimport type {\n DownloadStreamingEvent,\n HttpMethod,\n RequestContext,\n RequestParamsType,\n ResponseType,\n RetryOptions,\n Schema,\n UploadStreamingEvent,\n} from './types'\nimport {\n generatePath,\n toStreamableRequest,\n toStreamableResponse,\n type PathParams,\n} from './utils'\n\n/**\n * Default retry configuration for HTTP requests\n */\nconst DEFAULT_RETRY_OPTIONS: Required<RetryOptions> = {\n maxRetries: 3,\n retryDelay: 300,\n backoffFactor: 2,\n retryStatusCodes: [429, 500, 502, 503, 504],\n retryNetworkErrors: true,\n maxRetryDelay: 30000,\n shouldRetry: () => true,\n}\n\nexport interface HttpRequestOptions<\n TBody = unknown,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n> {\n /** HTTP method */\n method?: HttpMethod\n /** Request headers */\n headers?: Record<string, string>\n /** Query parameters */\n params?: TParams\n /** Path parameters for URL template */\n pathParams?: Record<string, string | number>\n /** Request body */\n body?: TBody\n /** Response schema for validation */\n schema?: Schema<TResponse>\n /** Custom timeout for this request */\n timeout?: number\n /** AbortSignal for request cancellation */\n signal?: AbortSignal\n /** Fetch options */\n credentials?: RequestCredentials\n cache?: RequestCache\n mode?: RequestMode\n redirect?: RequestRedirect\n /** Upload streaming tracking for this specific request */\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n /** Download streaming tracking for this specific request */\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n /** Custom status validation */\n validateStatus?: (status: number) => boolean\n /** Response type override */\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n /** Retry options for this specific request */\n retryOptions?: RetryOptions\n}\n\nexport interface HttpClientConfig {\n /** Base URL for all requests */\n baseUrl?: string\n /** Default headers */\n headers?: Record<string, string>\n /** Default timeout */\n timeout?: number\n /** Schema validator */\n schemaValidator?: SchemaValidator\n /** Default retry options */\n retryOptions?: RetryOptions\n /** Request middleware - can modify request before sending */\n onRequestMiddleware?: <TBody = unknown>(\n context: RequestContext<TBody>\n ) => RequestContext<TBody> | Promise<RequestContext<TBody>>\n /** Response middleware - can modify response after receiving */\n onResponseMiddleware?: (\n response: ResponseType<unknown>\n ) => ResponseType<unknown> | Promise<ResponseType<unknown>>\n}\n\n/**\n * Creates an HTTP request handler with the given configuration.\n * This is the core function that handles all HTTP requests with retry logic,\n * interceptors, streaming, and schema validation.\n */\nexport function createHttpRequest(config: HttpClientConfig = {}) {\n const {\n baseUrl = '',\n headers: defaultHeaders = {},\n timeout: defaultTimeout = 30_000,\n schemaValidator = createSchemaValidator(),\n onRequestMiddleware,\n onResponseMiddleware,\n } = config\n\n return async function fetcher<\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: HttpRequestOptions<TBody, TResponse, TParams> = {}\n ): Promise<ResponseType<TResponse>> {\n const {\n method = 'GET',\n headers = {},\n params,\n pathParams,\n body,\n schema,\n timeout = defaultTimeout,\n signal,\n credentials,\n cache,\n mode,\n redirect,\n onUploadStreaming,\n onDownloadStreaming,\n validateStatus,\n responseType,\n retryOptions: requestRetryOptions,\n } = options\n\n let resolvedUrl = generatePath(url, pathParams as PathParams<Path>)\n if (baseUrl) {\n resolvedUrl = new URL(resolvedUrl, baseUrl).toString()\n }\n\n let requestContext: RequestContext<TBody> = {\n url: resolvedUrl,\n method,\n params,\n headers: new Headers({ ...defaultHeaders, ...headers }),\n body,\n signal,\n fetchOptions: { credentials, cache, mode, redirect },\n }\n\n if (onRequestMiddleware) {\n try {\n requestContext = await onRequestMiddleware(requestContext)\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Request middleware failed', error),\n 'request',\n requestContext.url,\n requestContext.method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n if (requestContext.params) {\n const urlObj = new URL(requestContext.url)\n Object.entries(requestContext.params).forEach(([key, value]) => {\n if (value != null) {\n urlObj.searchParams.set(key, String(value))\n }\n })\n requestContext.url = urlObj.toString()\n }\n\n const requestInit: RequestInit = {\n method: requestContext.method,\n headers: requestContext.headers,\n ...requestContext.fetchOptions,\n }\n\n if (\n requestContext.body !== undefined &&\n ['POST', 'PUT', 'PATCH'].includes(requestContext.method)\n ) {\n const { body, contentType } = serializeRequestBody(requestContext.body)\n requestInit.body = body\n\n if (contentType) {\n requestContext.headers.set('content-type', contentType)\n }\n\n ;(requestInit as any).duplex = 'half'\n }\n\n const mergedRetryOptions = {\n ...DEFAULT_RETRY_OPTIONS,\n ...config.retryOptions,\n ...requestRetryOptions,\n }\n const maxRetries = mergedRetryOptions.maxRetries\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const finalSignal = requestContext.signal\n ? (() => {\n if (requestContext.signal && requestContext.signal.aborted) {\n return requestContext.signal\n }\n\n const combinedController = new AbortController()\n const cleanup = () => {\n clearTimeout(timeoutId)\n combinedController.abort()\n }\n\n requestContext.signal?.addEventListener('abort', cleanup)\n controller.signal.addEventListener('abort', cleanup)\n\n return combinedController.signal\n })()\n : controller.signal\n\n try {\n const request = new Request(requestContext.url, requestInit)\n const trackedRequest = onUploadStreaming\n ? await toStreamableRequest(request, onUploadStreaming)\n : request\n\n const response = await fetch(trackedRequest.url, {\n method: trackedRequest.method,\n headers: trackedRequest.headers,\n body: trackedRequest.body,\n signal: finalSignal,\n ...requestContext.fetchOptions,\n ...(trackedRequest.body && { duplex: 'half' as const }),\n })\n\n const trackedResponse = onDownloadStreaming\n ? await toStreamableResponse(response, onDownloadStreaming)\n : response\n\n const responseData = await processResponse<TResponse>(\n trackedResponse,\n {\n validateStatus,\n schema,\n responseType,\n },\n method,\n requestContext.url,\n schemaValidator\n )\n\n if (onResponseMiddleware) {\n try {\n return (await onResponseMiddleware(\n responseData\n )) as ResponseType<TResponse>\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Response middleware failed', error),\n 'response',\n requestContext.url,\n method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseData\n } catch (error) {\n clearTimeout(timeoutId)\n lastError = error instanceof Error ? error : new Error(String(error))\n\n if (lastError.name === 'AbortError') {\n lastError = new TimeoutError(\n `Request timeout after ${timeout}ms`,\n lastError\n )\n }\n\n if (\n attempt < maxRetries &&\n (await shouldRetry(lastError, attempt, mergedRetryOptions))\n ) {\n const delay = calculateRetryDelay(attempt, mergedRetryOptions)\n await sleep(delay)\n continue\n }\n\n throw lastError\n }\n }\n\n throw lastError || new Error('Request failed')\n }\n}\n\n/**\n * Helper function to process response (extracted from HttpClient)\n */\nasync function processResponse<T>(\n response: Response,\n options: {\n validateStatus?: (status: number) => boolean\n schema?: Schema<T>\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n },\n method: HttpMethod,\n url: string,\n schemaValidator: SchemaValidator\n): Promise<ResponseType<T>> {\n const headers = Object.fromEntries(response.headers.entries())\n\n const validateStatus =\n options.validateStatus ||\n ((status: number) => status >= 200 && status < 300)\n\n let data: unknown\n try {\n if (options.responseType === 'text') {\n data = await response.text()\n } else if (options.responseType === 'blob') {\n data = await response.blob()\n } else if (options.responseType === 'arrayBuffer') {\n data = await response.arrayBuffer()\n } else {\n const contentType = response.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n data = await response.json()\n } else if (contentType?.includes('text/')) {\n data = await response.text()\n } else {\n data = await response.arrayBuffer()\n }\n }\n } catch (error) {\n throw new SerializationError(\n createErrorMessage('Failed to parse response body', error),\n error instanceof Error ? error : undefined\n )\n }\n\n if (!validateStatus(response.status)) {\n throw new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n data,\n response,\n url,\n method\n )\n }\n\n const responseObj: ResponseType<T> = {\n data: data as T,\n status: response.status,\n statusText: response.statusText,\n headers,\n method,\n url,\n raw: response,\n }\n\n if (options.schema) {\n try {\n responseObj.data = schemaValidator.validate(\n options.schema,\n responseObj.data\n ) as T\n } catch (error) {\n throw new SchemaValidationError(\n `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`,\n options.schema,\n responseObj.data,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseObj\n}\n\n/**\n * Determines if a request should be retried based on error type and retry configuration\n */\nasync function shouldRetry(\n error: Error,\n retryCount: number,\n retryOptions?: RetryOptions\n): Promise<boolean> {\n if (!retryOptions) return false\n\n if (retryOptions.shouldRetry) {\n return await retryOptions.shouldRetry(error, retryCount)\n }\n\n if (error instanceof HttpError) {\n return retryOptions.retryStatusCodes?.includes(error.status) ?? false\n }\n\n if (error instanceof NetworkError || error.name === 'TypeError') {\n return retryOptions.retryNetworkErrors ?? false\n }\n\n return false\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n */\nfunction calculateRetryDelay(\n attempt: number,\n retryOptions?: RetryOptions\n): number {\n if (!retryOptions) return 0\n\n const baseDelay = retryOptions.retryDelay ?? 300\n const backoffFactor = retryOptions.backoffFactor ?? 2\n const maxDelay = retryOptions.maxRetryDelay ?? 30000\n\n const delay = baseDelay * Math.pow(backoffFactor, attempt)\n return Math.min(delay, maxDelay)\n}\n\n\n\n/**\n * Serializes request body based on type\n */\nfunction serializeRequestBody(body: unknown): { body: BodyInit; contentType?: string } {\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof ArrayBuffer ||\n body instanceof Blob ||\n body instanceof ReadableStream\n ) {\n return { body: body as BodyInit }\n }\n\n if (body !== null && body !== undefined) {\n return {\n body: JSON.stringify(body),\n contentType: 'application/json'\n }\n }\n\n return { body: '' }\n}\n\n/**\n * Creates a standardized error message\n */\nfunction createErrorMessage(context: string, error: unknown): string {\n return `${context}: ${error instanceof Error ? error.message : String(error)}`\n}\n\n/**\n * Creates a promise that resolves after the specified delay\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n","import { PathParameterError } from '../errors'\n\n/**\n * Strips protocol from URL (e.g., https://, http://)\n */\ntype StripProtocol<T extends string> = T extends `${string}://${infer After}`\n ? After\n : T\n\n/**\n * Strips host and optional port from URL, keeping only the path\n * Handles cases like \"localhost:3000/users\" -> \"/users\"\n */\ntype StripHost<T extends string> = T extends `${infer _Host}/${infer Path}`\n ? `/${Path}`\n : T\n\n/**\n * Strips query string from path (e.g., \"/users?x=1\" -> \"/users\")\n * Only strips ? that comes after the path, not ? that's part of path parameters\n */\ntype StripQuery<T extends string> = T extends `${infer Path}?${infer Query}`\n ? Query extends\n | `${string}=${string}`\n | `${string}=${string}&${string}`\n | `${string}&${string}`\n ? Path // contains = or &\n : Query extends `/${string}`\n ? T // it's another path segment\n : Query extends ``\n ? T // it's an optional param marker\n : Path // plain query params like ?param\n : T\n\n/**\n * Normalizes URL to path only, stripping protocol, host, port, and query\n */\ntype NormalizePath<T extends string> = StripQuery<StripHost<StripProtocol<T>>>\n\n/**\n * Removes optional suffix from param name (e.g., \":id?\" -> \"id\", \":id\" -> \"id\")\n */\ntype CleanParamName<S extends string> = S extends `:${infer Name}?`\n ? Name\n : S extends `:${infer Name}`\n ? Name\n : S\n\n/**\n * Extracts all path parameters from a route\n */\nexport type ExtractRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? CleanParamName<`:${Param}`> | ExtractRouteParams<`/${Rest}`>\n : CleanParamName<`:${AfterColon}`>\n : never\n\nexport type HasRequiredParams<T extends string> = [\n ExtractRouteParams<T>,\n] extends [never]\n ? false\n : true\n\n/**\n * PathParams type - extracts parameter names and their types\n */\nexport type PathParams<Path extends string> = {\n [K in ExtractRouteParams<Path>]: string | number\n}\n\n/**\n * RequirePathParams enforces pathParams when needed\n */\nexport type RequirePathParams<Path extends string, T> =\n HasRequiredParams<Path> extends true\n ? T & { pathParams: PathParams<Path> }\n : T\n\n/**\n * Interpolates parameters into a URL template\n * Similar to React Router's generatePath function\n *\n * @example\n * ```ts\n * const path = generatePath('/users/:id/posts/:postId', { id: '123', postId: '456' });\n * // => '/users/123/posts/456'\n * ```\n */\nexport function generatePath<Path extends string>(\n path: Path,\n params: PathParams<Path> = {} as PathParams<Path>\n): string {\n return path.replace(/:([a-zA-Z0-9_]+)/g, (_match, paramName: string) => {\n if (params[paramName as keyof PathParams<Path>] === undefined) {\n throw new PathParameterError(\n `Missing required path parameter: ${paramName}`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n return String(params[paramName as keyof PathParams<Path>])\n })\n}\n","import type { HttpClientConfig, HttpRequestOptions } from './core'\nimport { createHttpRequest } from './core'\nimport { InvalidBaseUrlError } from './errors'\nimport type {\n EnforcedPathParamsOptions,\n InferSchemaOutput,\n RequestParamsType,\n ResponseType,\n Schema,\n SchemaInferredRequestOptions,\n} from './types'\nimport type { HasRequiredParams } from './utils'\n\nfunction validateAndNormalizeBaseUrl(baseUrl?: string): string {\n const hasLocation =\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined' &&\n window.location.origin !== 'null'\n\n if (!baseUrl) {\n // In browser environment, default to location.origin for relative paths\n return hasLocation ? window.location.origin : ''\n }\n\n if (baseUrl.startsWith('/')) {\n // In Node.js or non-browser environments, relative paths are preserved as-is\n return hasLocation\n ? new URL(baseUrl, window.location.origin).href.replace(/\\/$/, '')\n : baseUrl.replace(/\\/$/, '')\n }\n\n try {\n new URL(baseUrl)\n } catch {\n throw new InvalidBaseUrlError(\n `Invalid baseUrl: \"${baseUrl}\". Must be a valid absolute URL or relative path starting with \"/\".`,\n baseUrl\n )\n }\n\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n}\n\ntype ResponsePromise<T> = Promise<ResponseType<T>> & {\n data(): Promise<T>\n}\n\n/**\n * Wraps a response promise to add the .data() method\n */\nfunction wrapResponsePromise<T>(\n promise: Promise<ResponseType<T>>\n): ResponsePromise<T> {\n const wrappedPromise = promise as ResponsePromise<T>\n wrappedPromise.data = async () => {\n const response = await promise\n return response.data\n }\n return wrappedPromise\n}\n\n/**\n * Creates a complete HTTP client with method builders\n */\nexport function createHttpClient(config: HttpClientConfig = {}) {\n const validatedConfig = {\n ...config,\n baseUrl: validateAndNormalizeBaseUrl(config.baseUrl),\n }\n\n const requestHandler = createHttpRequest(validatedConfig)\n\n function get<\n ResponseSchema extends Schema,\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: SchemaInferredRequestOptions<never, TParams, Path> & {\n schema: ResponseSchema\n }\n ): ResponsePromise<InferSchemaOutput<ResponseSchema>>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ): ResponsePromise<TResponse>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(url: Path, ...args: any[]) {\n return wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'GET',\n })\n )\n }\n\n return {\n get,\n\n post: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'POST',\n body,\n })\n ),\n\n put: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PUT',\n body,\n })\n ),\n\n patch: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PATCH',\n body,\n })\n ),\n\n delete: <\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'DELETE',\n })\n ),\n\n /**\n * Generic request method for custom HTTP methods and full control\n * Similar to native fetch but with 1000fetches features\n */\n request: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options?: HttpRequestOptions<TBody, TResponse, TParams>\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, options)\n ),\n }\n}\n\nexport const http = createHttpClient()\n"],"names":["HttpError","Error","name","status","statusText","data","response","url","method","cause","constructor","message","super","this","NetworkError","SchemaValidationError","schema","TimeoutError","PathParameterError","requiredParams","providedParams","MiddlewareError","interceptorType","SerializationError","InvalidSchemaError","AsyncSchemaValidationError","InvalidBaseUrlError","baseUrl","isStandardSchema","obj","validate","version","vendor","createSchemaValidator","result","Promise","issues","JSON","stringify","value","isSchema","createStreamingStream","reader","onChunk","totalBytes","transferredBytes","ReadableStream","start","controller","done","read","length","enqueue","releaseLock","close","async","toStreamableRequest","request","onUploadStreaming","body","stream","getReader","chunk","headers","get","parseInt","Request","signal","credentials","cache","mode","redirect","referrer","referrerPolicy","integrity","keepalive","duplex","toStreamableResponse","onDownloadStreaming","Response","DEFAULT_RETRY_OPTIONS","maxRetries","retryDelay","backoffFactor","retryStatusCodes","retryNetworkErrors","maxRetryDelay","shouldRetry","createHttpRequest","config","defaultHeaders","timeout","defaultTimeout","schemaValidator","onRequestMiddleware","onResponseMiddleware","options","params","pathParams","validateStatus","responseType","retryOptions","requestRetryOptions","resolvedUrl","path","replace","_match","paramName","Object","keys","String","generatePath","URL","toString","requestContext","Headers","fetchOptions","error","createErrorMessage","urlObj","entries","forEach","key","searchParams","set","requestInit","includes","contentType","FormData","URLSearchParams","ArrayBuffer","Blob","serializeRequestBody","mergedRetryOptions","lastError","attempt","AbortController","timeoutId","setTimeout","abort","finalSignal","aborted","combinedController","cleanup","clearTimeout","addEventListener","trackedRequest","fetch","trackedResponse","responseData","processResponse","delay","calculateRetryDelay","sleep","fromEntries","text","blob","arrayBuffer","json","responseObj","raw","retryCount","baseDelay","maxDelay","Math","pow","min","context","ms","resolve","validateAndNormalizeBaseUrl","hasLocation","window","location","origin","startsWith","href","endsWith","slice","wrapResponsePromise","promise","wrappedPromise","createHttpClient","requestHandler","args","post","put","patch","delete","http"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/errors.ts","../src/schema.ts","../src/utils/streaming.ts","../src/core.ts","../src/utils/path.ts","../src/client.ts"],"sourcesContent":["interface HttpClientError {\n name: string\n message: string\n cause?: Error\n stack?: string\n}\n\nexport class HttpError<TErrorData = unknown>\n extends Error\n implements HttpClientError\n{\n public readonly name = 'HttpError'\n public readonly status: number\n public readonly statusText: string\n public readonly data: TErrorData\n public readonly response: Response\n public readonly url: string\n public readonly method: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n data: TErrorData,\n response: Response,\n url: string,\n method: string,\n cause?: Error\n ) {\n const enhancedMessage = `HTTP ${status} ${statusText}: ${message} (${method} ${url})`\n super(enhancedMessage, { cause })\n this.status = status\n this.statusText = statusText\n this.data = data\n this.response = response\n this.url = url\n this.method = method\n }\n}\n\nexport class NetworkError extends Error implements HttpClientError {\n public readonly name = 'NetworkError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class SchemaValidationError extends Error implements HttpClientError {\n public readonly name = 'SchemaValidationError'\n public readonly schema: unknown\n public readonly data: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, data: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.data = data\n }\n}\n\nexport class TimeoutError extends Error implements HttpClientError {\n public readonly name = 'TimeoutError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class PathParameterError extends Error implements HttpClientError {\n public readonly name = 'PathParameterError'\n public readonly url: string\n public readonly requiredParams: string[]\n public readonly providedParams: string[]\n public override readonly cause?: Error\n\n constructor(\n message: string,\n url: string,\n requiredParams: string[],\n providedParams: string[],\n cause?: Error\n ) {\n super(message, { cause })\n this.url = url\n this.requiredParams = requiredParams\n this.providedParams = providedParams\n }\n}\n\nexport class MiddlewareError extends Error implements HttpClientError {\n public readonly name = 'MiddlewareError'\n public readonly interceptorType: 'request' | 'response'\n public readonly url?: string\n public readonly method?: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n interceptorType: 'request' | 'response',\n url?: string,\n method?: string,\n cause?: Error\n ) {\n super(message, { cause })\n this.interceptorType = interceptorType\n this.url = url\n this.method = method\n }\n}\n\nexport class SerializationError extends Error implements HttpClientError {\n public readonly name = 'SerializationError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class InvalidSchemaError extends Error implements HttpClientError {\n public readonly name = 'InvalidSchemaError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class AsyncSchemaValidationError\n extends Error\n implements HttpClientError\n{\n public readonly name = 'AsyncSchemaValidationError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class InvalidBaseUrlError extends Error implements HttpClientError {\n public readonly name = 'InvalidBaseUrlError'\n public readonly baseUrl: string\n public override readonly cause?: Error\n\n constructor(message: string, baseUrl: string, cause?: Error) {\n super(message, { cause })\n this.baseUrl = baseUrl\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport {\n AsyncSchemaValidationError,\n InvalidSchemaError,\n SchemaValidationError,\n} from './errors'\nimport { Schema } from './types'\n\n/**\n * Type guard to check if an object conforms to the Standard Schema V1 specification\n */\nfunction isStandardSchema(obj: unknown): obj is StandardSchemaV1 {\n return (\n obj !== null &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n '~standard' in obj &&\n typeof obj['~standard'] === 'object' &&\n obj['~standard'] !== null &&\n 'validate' in obj['~standard'] &&\n typeof obj['~standard'].validate === 'function' &&\n 'version' in obj['~standard'] &&\n typeof obj['~standard'].version === 'number' &&\n 'vendor' in obj['~standard'] &&\n typeof obj['~standard'].vendor === 'string'\n )\n}\n\n/**\n * Interface for schema validators that can validate data against schemas.\n *\n * This interface allows you to create custom schema validators that work\n * with different validation libraries (Zod, Valibot, Arktype, etc.).\n */\nexport interface SchemaValidator {\n /**\n * Validate data against a schema.\n *\n * @template T - The expected type after validation\n * @param schema - The schema to validate against\n * @param data - The data to validate\n * @returns The validated data with the correct type\n * @throws {SchemaValidationError} If the data doesn't match the schema\n */\n validate<T>(schema: Schema<T>, data: unknown): T\n\n /**\n * Check if an object is a valid schema.\n *\n * @param obj - The object to check\n * @returns True if the object is a valid schema, false otherwise\n */\n isSchema(obj: unknown): boolean\n}\n\n/**\n * Create a default schema validator that supports Standard Schema.\n *\n * This validator only works with schemas that implement the Standard Schema\n * interface. For full support of Zod, Valibot, and Arktype, use the\n * appropriate validator from their respective packages.\n *\n * @returns A schema validator instance\n *\n * @example\n * ```ts\n * import { createSchemaValidator } from '1000fetches'\n *\n * const validator = createSchemaValidator();\n *\n * // Use with HttpClient\n * const client = new HttpClient({\n * schemaValidator: validator\n * });\n * ```\n */\nexport function createSchemaValidator(): SchemaValidator {\n return {\n validate<T>(schema: Schema<T>, data: unknown): T {\n if (!isStandardSchema(schema)) {\n throw new InvalidSchemaError(\n 'Schema must implement the Standard Schema interface',\n schema\n )\n }\n\n const result = schema['~standard'].validate(data)\n\n if (result instanceof Promise) {\n throw new AsyncSchemaValidationError(\n 'Async Standard Schema validation is not supported in this context',\n schema\n )\n }\n\n if (result.issues) {\n throw new SchemaValidationError(\n JSON.stringify(result.issues),\n schema,\n data\n )\n }\n\n return result.value as T\n },\n\n isSchema(obj: unknown): boolean {\n return isStandardSchema(obj)\n },\n }\n}\n","import type { DownloadStreamingEvent, UploadStreamingEvent } from '../types'\n\nfunction createStreamingStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onChunk: (\n chunk: Uint8Array,\n totalBytes: number | undefined,\n transferredBytes: number\n ) => void,\n totalBytes: number | undefined\n): ReadableStream<Uint8Array> {\n let transferredBytes = 0\n\n return new ReadableStream({\n async start(controller) {\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n transferredBytes += value.length\n onChunk(value, totalBytes, transferredBytes)\n controller.enqueue(value)\n }\n } finally {\n reader.releaseLock()\n controller.close()\n }\n },\n })\n}\n\n/**\n * Creates a request with upload streaming tracking\n */\nexport async function toStreamableRequest(\n request: Request,\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n): Promise<Request> {\n if (!onUploadStreaming || !request.body) {\n return request\n }\n\n const reader = request.body.getReader()\n const totalBytes = request.headers.get('content-length')\n ? parseInt(request.headers.get('content-length') || '0', 10)\n : 0\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes: totalBytes as number, // Safe cast since we pass 0 as default\n transferredBytes,\n })\n },\n totalBytes\n )\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n signal: request.signal,\n credentials: request.credentials,\n cache: request.cache,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n integrity: request.integrity,\n keepalive: request.keepalive,\n duplex: 'half',\n } as RequestInit)\n}\n\n/**\n * Creates a response with download streaming tracking\n */\nexport async function toStreamableResponse(\n response: Response,\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n): Promise<Response> {\n if (!onDownloadStreaming || !response.body) {\n return response\n }\n\n const reader = response.body.getReader()\n const totalBytes = response.headers.get('content-length')\n ? parseInt(response.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onDownloadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n },\n totalBytes\n )\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n}\n","import {\n HttpError,\n MiddlewareError,\n NetworkError,\n SchemaValidationError,\n SerializationError,\n TimeoutError,\n} from './errors'\nimport { createSchemaValidator, type SchemaValidator } from './schema'\nimport type {\n CustomFetch,\n DownloadStreamingEvent,\n HttpMethod,\n RequestContext,\n RequestParamsType,\n ResponseType,\n RetryOptions,\n Schema,\n SerializeBody,\n SerializeParams,\n UploadStreamingEvent,\n} from './types'\nimport {\n generatePath,\n toStreamableRequest,\n toStreamableResponse,\n type PathParams,\n} from './utils'\n\n/**\n * Default retry configuration for HTTP requests\n */\nconst DEFAULT_RETRY_OPTIONS: Required<RetryOptions> = {\n maxRetries: 3,\n retryDelay: 300,\n backoffFactor: 2,\n retryStatusCodes: [429, 500, 502, 503, 504],\n retryNetworkErrors: true,\n maxRetryDelay: 30000,\n shouldRetry: () => true,\n}\n\nexport interface HttpRequestOptions<\n TBody = unknown,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n> {\n /** HTTP method */\n method?: HttpMethod\n /** Request headers */\n headers?: Record<string, string>\n /** Query parameters */\n params?: TParams\n /** Path parameters for URL template */\n pathParams?: Record<string, string | number>\n /** Request body */\n body?: TBody\n /** Response schema for validation */\n schema?: Schema<TResponse>\n /** Custom timeout for this request */\n timeout?: number\n /** AbortSignal for request cancellation */\n signal?: AbortSignal\n /** Fetch options */\n credentials?: RequestCredentials\n cache?: RequestCache\n mode?: RequestMode\n redirect?: RequestRedirect\n /** Upload streaming tracking for this specific request */\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n /** Download streaming tracking for this specific request */\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n /** Custom status validation */\n validateStatus?: (status: number) => boolean\n /** Response type override */\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n /** Retry options for this specific request */\n retryOptions?: RetryOptions\n}\n\nexport interface HttpClientConfig {\n /** Base URL for all requests */\n baseUrl?: string\n /** Default headers */\n headers?: Record<string, string>\n /** Default timeout */\n timeout?: number\n /** Schema validator */\n schemaValidator?: SchemaValidator\n /** Default retry options */\n retryOptions?: RetryOptions\n /** Custom fetch implementation */\n fetch?: CustomFetch\n /** Custom body serializer */\n serializeBody?: SerializeBody\n /** Custom params serializer */\n serializeParams?: SerializeParams\n /** Request middleware - can modify request before sending */\n onRequestMiddleware?: <TBody = unknown>(\n context: RequestContext<TBody>\n ) => RequestContext<TBody> | Promise<RequestContext<TBody>>\n /** Response middleware - can modify response after receiving */\n onResponseMiddleware?: (\n response: ResponseType<unknown>\n ) => ResponseType<unknown> | Promise<ResponseType<unknown>>\n}\n\n/**\n * Creates an HTTP request handler with the given configuration.\n * This is the core function that handles all HTTP requests with retry logic,\n * interceptors, streaming, and schema validation.\n */\nexport function createHttpRequest(config: HttpClientConfig = {}) {\n const {\n baseUrl = '',\n headers: defaultHeaders = {},\n timeout: defaultTimeout = 30_000,\n schemaValidator = createSchemaValidator(),\n fetch: customFetch = fetch,\n serializeBody: customSerializeBody,\n serializeParams: customSerializeParams,\n onRequestMiddleware,\n onResponseMiddleware,\n } = config\n\n return async function fetcher<\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: HttpRequestOptions<TBody, TResponse, TParams> = {}\n ): Promise<ResponseType<TResponse>> {\n const {\n method = 'GET',\n headers = {},\n params,\n pathParams,\n body,\n schema,\n timeout = defaultTimeout,\n signal,\n credentials,\n cache,\n mode,\n redirect,\n onUploadStreaming,\n onDownloadStreaming,\n validateStatus,\n responseType,\n retryOptions: requestRetryOptions,\n } = options\n\n let resolvedUrl = generatePath(url, pathParams as PathParams<Path>)\n if (baseUrl) {\n resolvedUrl = new URL(resolvedUrl, baseUrl).toString()\n }\n\n let requestContext: RequestContext<TBody> = {\n url: resolvedUrl,\n method,\n params,\n headers: new Headers({ ...defaultHeaders, ...headers }),\n body,\n signal,\n fetchOptions: { credentials, cache, mode, redirect },\n }\n\n if (onRequestMiddleware) {\n try {\n requestContext = await onRequestMiddleware(requestContext)\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Request middleware failed', error),\n 'request',\n requestContext.url,\n requestContext.method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n if (requestContext.params) {\n const urlObj = new URL(requestContext.url)\n const serializedParams = customSerializeParams\n ? customSerializeParams(requestContext.params)\n : new URLSearchParams(\n JSON.parse(JSON.stringify(requestContext.params)) as Record<\n string,\n string\n >\n ).toString()\n\n if (serializedParams) {\n const queryString =\n customSerializeParams && serializedParams.startsWith('?')\n ? serializedParams.slice(1)\n : serializedParams\n urlObj.search = queryString\n }\n\n requestContext.url = urlObj.toString()\n }\n\n const requestInit: RequestInit = {\n method: requestContext.method,\n headers: requestContext.headers,\n ...requestContext.fetchOptions,\n }\n\n if (\n requestContext.body !== undefined &&\n (requestContext.method === 'POST' ||\n requestContext.method === 'PUT' ||\n requestContext.method === 'PATCH')\n ) {\n let body: BodyInit\n let contentType: string | undefined\n\n if (customSerializeBody) {\n const serializedBody = customSerializeBody(requestContext.body)\n if (serializedBody == null) {\n body = ''\n } else {\n body = serializedBody\n\n if (\n isObjectLike(requestContext.body) &&\n typeof serializedBody === 'string' &&\n !requestContext.headers.has('content-type')\n ) {\n contentType = 'application/json'\n }\n }\n } else {\n const serialized = serializeRequestBody(requestContext.body)\n body = serialized.body\n contentType = serialized.contentType\n }\n\n requestInit.body = body\n\n if (contentType) {\n requestContext.headers.set('content-type', contentType)\n }\n\n ;(requestInit as any).duplex = 'half'\n }\n\n const mergedRetryOptions = {\n ...DEFAULT_RETRY_OPTIONS,\n ...config.retryOptions,\n ...requestRetryOptions,\n }\n const maxRetries = mergedRetryOptions.maxRetries\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const finalSignal = requestContext.signal\n ? (() => {\n if (requestContext.signal && requestContext.signal.aborted) {\n return requestContext.signal\n }\n\n const combinedController = new AbortController()\n const cleanup = () => {\n clearTimeout(timeoutId)\n combinedController.abort()\n }\n\n requestContext.signal?.addEventListener('abort', cleanup)\n controller.signal.addEventListener('abort', cleanup)\n\n return combinedController.signal\n })()\n : controller.signal\n\n try {\n const request = new Request(requestContext.url, requestInit)\n const trackedRequest = onUploadStreaming\n ? await toStreamableRequest(request, onUploadStreaming)\n : request\n\n const response = await customFetch(trackedRequest.url, {\n method: trackedRequest.method,\n headers: trackedRequest.headers,\n body: trackedRequest.body,\n signal: finalSignal,\n ...requestContext.fetchOptions,\n ...(trackedRequest.body && { duplex: 'half' as const }),\n })\n\n const trackedResponse = onDownloadStreaming\n ? await toStreamableResponse(response, onDownloadStreaming)\n : response\n\n const responseData = await processResponse<TResponse>(\n trackedResponse,\n {\n validateStatus,\n schema,\n responseType,\n },\n method,\n requestContext.url,\n schemaValidator\n )\n\n if (onResponseMiddleware) {\n try {\n return (await onResponseMiddleware(\n responseData\n )) as ResponseType<TResponse>\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Response middleware failed', error),\n 'response',\n requestContext.url,\n method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseData\n } catch (error) {\n clearTimeout(timeoutId)\n lastError = error instanceof Error ? error : new Error(String(error))\n\n if (lastError.name === 'AbortError') {\n lastError = new TimeoutError(\n `Request timeout after ${timeout}ms`,\n lastError\n )\n }\n\n if (\n attempt < maxRetries &&\n (await shouldRetry(lastError, attempt, mergedRetryOptions))\n ) {\n const delay = calculateRetryDelay(attempt, mergedRetryOptions)\n await sleep(delay)\n continue\n }\n\n throw lastError\n }\n }\n\n throw lastError || new Error('Request failed')\n }\n}\n\n/**\n * Helper function to process response (extracted from HttpClient)\n */\nasync function processResponse<T>(\n response: Response,\n options: {\n validateStatus?: (status: number) => boolean\n schema?: Schema<T>\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n },\n method: HttpMethod,\n url: string,\n schemaValidator: SchemaValidator\n): Promise<ResponseType<T>> {\n const headers = Object.fromEntries(response.headers.entries())\n\n const validateStatus =\n options.validateStatus ||\n ((status: number) => status >= 200 && status < 300)\n\n let data: unknown\n try {\n if (options.responseType === 'text') {\n data = await response.text()\n } else if (options.responseType === 'blob') {\n data = await response.blob()\n } else if (options.responseType === 'arrayBuffer') {\n data = await response.arrayBuffer()\n } else {\n const contentType = response.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n data = await response.json()\n } else if (contentType?.includes('text/')) {\n data = await response.text()\n } else {\n data = await response.arrayBuffer()\n }\n }\n } catch (error) {\n throw new SerializationError(\n createErrorMessage('Failed to parse response body', error),\n error instanceof Error ? error : undefined\n )\n }\n\n if (!validateStatus(response.status)) {\n throw new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n data,\n response,\n url,\n method\n )\n }\n\n const responseObj: ResponseType<T> = {\n data: data as T,\n status: response.status,\n statusText: response.statusText,\n headers,\n method,\n url,\n raw: response,\n }\n\n if (options.schema) {\n try {\n responseObj.data = schemaValidator.validate(\n options.schema,\n responseObj.data\n ) as T\n } catch (error) {\n throw new SchemaValidationError(\n `Schema validation failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n options.schema,\n responseObj.data,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseObj\n}\n\n/**\n * Determines if a request should be retried based on error type and retry configuration\n */\nasync function shouldRetry(\n error: Error,\n retryCount: number,\n retryOptions?: RetryOptions\n): Promise<boolean> {\n if (!retryOptions) return false\n\n if (retryOptions.shouldRetry) {\n return await retryOptions.shouldRetry(error, retryCount)\n }\n\n if (error instanceof HttpError) {\n return retryOptions.retryStatusCodes?.includes(error.status) ?? false\n }\n\n if (error instanceof NetworkError || error.name === 'TypeError') {\n return retryOptions.retryNetworkErrors ?? false\n }\n\n return false\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n */\nfunction calculateRetryDelay(\n attempt: number,\n retryOptions?: RetryOptions\n): number {\n if (!retryOptions) return 0\n\n const baseDelay = retryOptions.retryDelay ?? 300\n const backoffFactor = retryOptions.backoffFactor ?? 2\n const maxDelay = retryOptions.maxRetryDelay ?? 30000\n\n const delay = baseDelay * Math.pow(backoffFactor, attempt)\n return Math.min(delay, maxDelay)\n}\n\n/**\n * Determines if a value should be JSON stringified (same as up-fetch)\n */\nfunction isObjectLike(\n value: any\n): value is Record<string, any> | any[] | { toJSON(): any } {\n return (\n (value &&\n typeof value === 'object' &&\n value.constructor?.name === 'Object') ||\n Array.isArray(value) ||\n typeof value?.toJSON === 'function'\n )\n}\n\n/**\n * Serializes request body based on type (same as up-fetch)\n */\nfunction serializeRequestBody(body: unknown): {\n body: BodyInit\n contentType?: string\n} {\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof ArrayBuffer ||\n body instanceof Blob ||\n body instanceof ReadableStream\n ) {\n return { body: body as BodyInit }\n }\n\n if (isObjectLike(body)) {\n return {\n body: JSON.stringify(body),\n contentType: 'application/json',\n }\n }\n\n return { body: body as BodyInit }\n}\n\n/**\n * Creates a standardized error message\n */\nfunction createErrorMessage(context: string, error: unknown): string {\n return `${context}: ${error instanceof Error ? error.message : String(error)}`\n}\n\n/**\n * Creates a promise that resolves after the specified delay\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n","import { PathParameterError } from '../errors'\n\n/**\n * Strips protocol from URL (e.g., https://, http://)\n */\ntype StripProtocol<T extends string> = T extends `${string}://${infer After}`\n ? After\n : T\n\n/**\n * Strips host and optional port from URL, keeping only the path\n * Handles cases like \"localhost:3000/users\" -> \"/users\"\n */\ntype StripHost<T extends string> = T extends `${infer _Host}/${infer Path}`\n ? `/${Path}`\n : T\n\n/**\n * Strips query string from path (e.g., \"/users?x=1\" -> \"/users\")\n * Only strips ? that comes after the path, not ? that's part of path parameters\n */\ntype StripQuery<T extends string> = T extends `${infer Path}?${infer Query}`\n ? Query extends\n | `${string}=${string}`\n | `${string}=${string}&${string}`\n | `${string}&${string}`\n ? Path // contains = or &\n : Query extends `/${string}`\n ? T // it's another path segment\n : Query extends ``\n ? T // it's an optional param marker\n : Path // plain query params like ?param\n : T\n\n/**\n * Normalizes URL to path only, stripping protocol, host, port, and query\n */\ntype NormalizePath<T extends string> = StripQuery<StripHost<StripProtocol<T>>>\n\n/**\n * Removes optional suffix from param name (e.g., \":id?\" -> \"id\", \":id\" -> \"id\")\n */\ntype CleanParamName<S extends string> = S extends `:${infer Name}?`\n ? Name\n : S extends `:${infer Name}`\n ? Name\n : S\n\n/**\n * Extracts all path parameters from a route\n */\nexport type ExtractRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? CleanParamName<`:${Param}`> | ExtractRouteParams<`/${Rest}`>\n : CleanParamName<`:${AfterColon}`>\n : never\n\nexport type HasRequiredParams<T extends string> = [\n ExtractRouteParams<T>,\n] extends [never]\n ? false\n : true\n\n/**\n * PathParams type - extracts parameter names and their types\n */\nexport type PathParams<Path extends string> = {\n [K in ExtractRouteParams<Path>]: string | number\n}\n\n/**\n * RequirePathParams enforces pathParams when needed\n */\nexport type RequirePathParams<Path extends string, T> =\n HasRequiredParams<Path> extends true\n ? T & { pathParams: PathParams<Path> }\n : T\n\n/**\n * Interpolates parameters into a URL template\n * Similar to React Router's generatePath function\n *\n * @example\n * ```ts\n * const path = generatePath('/users/:id/posts/:postId', { id: '123', postId: '456' });\n * // => '/users/123/posts/456'\n * ```\n */\nexport function generatePath<Path extends string>(\n path: Path,\n params: PathParams<Path> = {} as PathParams<Path>\n): string {\n return path.replace(/:([a-zA-Z0-9_]+)/g, (_match, paramName: string) => {\n if (params[paramName as keyof PathParams<Path>] === undefined) {\n throw new PathParameterError(\n `Missing required path parameter: ${paramName}`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n return String(params[paramName as keyof PathParams<Path>])\n })\n}\n","import type { HttpClientConfig, HttpRequestOptions } from './core'\nimport { createHttpRequest } from './core'\nimport { InvalidBaseUrlError } from './errors'\nimport type {\n EnforcedPathParamsOptions,\n InferSchemaOutput,\n RequestParamsType,\n ResponseType,\n Schema,\n SchemaInferredRequestOptions,\n} from './types'\nimport type { HasRequiredParams } from './utils'\n\nfunction validateAndNormalizeBaseUrl(baseUrl?: string): string {\n const hasLocation =\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined' &&\n window.location.origin !== 'null'\n\n if (!baseUrl) {\n // In browser environment, default to location.origin for relative paths\n return hasLocation ? window.location.origin : ''\n }\n\n if (baseUrl.startsWith('/')) {\n // In Node.js or non-browser environments, relative paths are preserved as-is\n return hasLocation\n ? new URL(baseUrl, window.location.origin).href.replace(/\\/$/, '')\n : baseUrl.replace(/\\/$/, '')\n }\n\n try {\n new URL(baseUrl)\n } catch {\n throw new InvalidBaseUrlError(\n `Invalid baseUrl: \"${baseUrl}\". Must be a valid absolute URL or relative path starting with \"/\".`,\n baseUrl\n )\n }\n\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n}\n\ntype ResponsePromise<T> = Promise<ResponseType<T>> & {\n data(): Promise<T>\n}\n\n/**\n * Wraps a response promise to add the .data() method\n */\nfunction wrapResponsePromise<T>(\n promise: Promise<ResponseType<T>>\n): ResponsePromise<T> {\n const wrappedPromise = promise as ResponsePromise<T>\n wrappedPromise.data = async () => {\n const response = await promise\n return response.data\n }\n return wrappedPromise\n}\n\n/**\n * Creates a complete HTTP client with method builders\n */\nexport function createHttpClient(config: HttpClientConfig = {}) {\n const validatedConfig = {\n ...config,\n baseUrl: validateAndNormalizeBaseUrl(config.baseUrl),\n }\n\n const requestHandler = createHttpRequest(validatedConfig)\n\n function get<\n ResponseSchema extends Schema,\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: SchemaInferredRequestOptions<\n never,\n InferSchemaOutput<ResponseSchema>,\n TParams,\n Path\n > & {\n schema: ResponseSchema\n }\n ): ResponsePromise<InferSchemaOutput<ResponseSchema>>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ): ResponsePromise<TResponse>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(url: Path, ...args: any[]) {\n return wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'GET',\n })\n )\n }\n\n return {\n get,\n\n post: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'POST',\n body,\n })\n ),\n\n put: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PUT',\n body,\n })\n ),\n\n patch: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PATCH',\n body,\n })\n ),\n\n delete: <\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'DELETE',\n })\n ),\n\n /**\n * Generic request method for custom HTTP methods and full control\n * Similar to native fetch but with 1000fetches features\n */\n request: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options?: HttpRequestOptions<TBody, TResponse, TParams>\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, options)\n ),\n }\n}\n\nexport const http = createHttpClient()\n"],"names":["HttpError","Error","name","status","statusText","data","response","url","method","cause","constructor","message","super","this","NetworkError","SchemaValidationError","schema","TimeoutError","PathParameterError","requiredParams","providedParams","MiddlewareError","interceptorType","SerializationError","InvalidSchemaError","AsyncSchemaValidationError","InvalidBaseUrlError","baseUrl","isStandardSchema","obj","validate","version","vendor","createSchemaValidator","result","Promise","issues","JSON","stringify","value","isSchema","createStreamingStream","reader","onChunk","totalBytes","transferredBytes","ReadableStream","start","controller","done","read","length","enqueue","releaseLock","close","async","toStreamableRequest","request","onUploadStreaming","body","stream","getReader","chunk","headers","get","parseInt","Request","signal","credentials","cache","mode","redirect","referrer","referrerPolicy","integrity","keepalive","duplex","toStreamableResponse","onDownloadStreaming","Response","DEFAULT_RETRY_OPTIONS","maxRetries","retryDelay","backoffFactor","retryStatusCodes","retryNetworkErrors","maxRetryDelay","shouldRetry","createHttpRequest","config","defaultHeaders","timeout","defaultTimeout","schemaValidator","fetch","customFetch","serializeBody","customSerializeBody","serializeParams","customSerializeParams","onRequestMiddleware","onResponseMiddleware","options","params","pathParams","validateStatus","responseType","retryOptions","requestRetryOptions","resolvedUrl","path","replace","_match","paramName","Object","keys","String","generatePath","URL","toString","requestContext","Headers","fetchOptions","error","createErrorMessage","urlObj","serializedParams","URLSearchParams","parse","queryString","startsWith","slice","search","requestInit","contentType","serializedBody","isObjectLike","has","serialized","FormData","ArrayBuffer","Blob","serializeRequestBody","set","mergedRetryOptions","lastError","attempt","AbortController","timeoutId","setTimeout","abort","finalSignal","aborted","combinedController","cleanup","clearTimeout","addEventListener","trackedRequest","trackedResponse","responseData","processResponse","delay","calculateRetryDelay","sleep","fromEntries","entries","text","blob","arrayBuffer","includes","json","responseObj","raw","retryCount","baseDelay","maxDelay","Math","pow","min","Array","isArray","toJSON","context","ms","resolve","validateAndNormalizeBaseUrl","hasLocation","window","location","origin","href","endsWith","wrapResponsePromise","promise","wrappedPromise","createHttpClient","requestHandler","args","post","put","patch","delete","http"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ declare type CleanParamName<S extends string> = S extends `:${infer Name}?` ? Na
17
17
  */
18
18
  export declare function createHttpClient(config?: HttpClientConfig): {
19
19
  get: {
20
- <ResponseSchema extends Schema, Path extends string = string, TParams extends RequestParamsType = RequestParamsType>(url: Path, options: SchemaInferredRequestOptions<never, TParams, Path> & {
20
+ <ResponseSchema extends Schema, Path extends string = string, TParams extends RequestParamsType = RequestParamsType>(url: Path, options: SchemaInferredRequestOptions<never, InferSchemaOutput<ResponseSchema>, TParams, Path> & {
21
21
  schema: ResponseSchema;
22
22
  }): ResponsePromise<InferSchemaOutput<ResponseSchema>>;
23
23
  <Path extends string = string, TResponse = unknown, TParams extends RequestParamsType = RequestParamsType>(url: Path, ...args: HasRequiredParams<Path> extends true ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>] : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]): ResponsePromise<TResponse>;
@@ -33,28 +33,7 @@ export declare function createHttpClient(config?: HttpClientConfig): {
33
33
  request: <Path extends string = string, TResponse = unknown, TBody = unknown, TParams extends RequestParamsType = RequestParamsType>(url: Path, options?: HttpRequestOptions<TBody, TResponse, TParams>) => ResponsePromise<TResponse>;
34
34
  };
35
35
 
36
- /**
37
- * Create a default schema validator that supports Standard Schema.
38
- *
39
- * This validator only works with schemas that implement the Standard Schema
40
- * interface. For full support of Zod, Valibot, and Arktype, use the
41
- * appropriate validator from their respective packages.
42
- *
43
- * @returns A schema validator instance
44
- *
45
- * @example
46
- * ```ts
47
- * import { createSchemaValidator } from '1000fetches'
48
- *
49
- * const validator = createSchemaValidator();
50
- *
51
- * // Use with HttpClient
52
- * const client = new HttpClient({
53
- * schemaValidator: validator
54
- * });
55
- * ```
56
- */
57
- export declare function createSchemaValidator(): SchemaValidator;
36
+ declare type CustomFetch = typeof fetch;
58
37
 
59
38
  declare interface DownloadStreamingEvent {
60
39
  /** Current data chunk being downloaded */
@@ -65,10 +44,6 @@ declare interface DownloadStreamingEvent {
65
44
  transferredBytes: number;
66
45
  }
67
46
 
68
- /**
69
- * Request options with enforced pathParams when the URL contains path parameters.
70
- * Use this to ensure compile-time safety for path parameters.
71
- */
72
47
  declare type EnforcedPathParamsOptions<TBody = unknown, TResponse = unknown, TParams extends RequestParamsType = RequestParamsType, Path extends string = string> = RequirePathParams<Path, Omit<RequestOptions<TBody>, 'params'> & {
73
48
  params?: TParams;
74
49
  schema?: Schema<TResponse>;
@@ -85,7 +60,7 @@ ExtractRouteParams<T>
85
60
 
86
61
  declare const http: {
87
62
  get: {
88
- <ResponseSchema extends Schema, Path extends string = string, TParams extends RequestParamsType = RequestParamsType>(url: Path, options: SchemaInferredRequestOptions<never, TParams, Path> & {
63
+ <ResponseSchema extends Schema, Path extends string = string, TParams extends RequestParamsType = RequestParamsType>(url: Path, options: SchemaInferredRequestOptions<never, InferSchemaOutput<ResponseSchema>, TParams, Path> & {
89
64
  schema: ResponseSchema;
90
65
  }): ResponsePromise<InferSchemaOutput<ResponseSchema>>;
91
66
  <Path extends string = string, TResponse = unknown, TParams extends RequestParamsType = RequestParamsType>(url: Path, ...args: HasRequiredParams<Path> extends true ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>] : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]): ResponsePromise<TResponse>;
@@ -114,6 +89,12 @@ export declare interface HttpClientConfig {
114
89
  schemaValidator?: SchemaValidator;
115
90
  /** Default retry options */
116
91
  retryOptions?: RetryOptions;
92
+ /** Custom fetch implementation */
93
+ fetch?: CustomFetch;
94
+ /** Custom body serializer */
95
+ serializeBody?: SerializeBody;
96
+ /** Custom params serializer */
97
+ serializeParams?: SerializeParams;
117
98
  /** Request middleware - can modify request before sending */
118
99
  onRequestMiddleware?: <TBody = unknown>(context: RequestContext<TBody>) => RequestContext<TBody> | Promise<RequestContext<TBody>>;
119
100
  /** Response middleware - can modify response after receiving */
@@ -177,15 +158,13 @@ export declare interface HttpRequestOptions<TBody = unknown, TResponse = unknown
177
158
 
178
159
  /**
179
160
  * Infer the output type from a Schema
180
- * For Zod schemas (with _def and parse), we infer from .parse() return type to support `schemaOf`
161
+ * For Zod schemas, we use z.infer (same as schemaOf)
181
162
  * For other StandardSchemaV1 schemas, we use StandardSchemaV1.InferOutput
182
163
  */
183
- declare type InferSchemaOutput<ResponseSchema extends StandardSchemaV1> = [
184
- ResponseSchema
185
- ] extends [{
164
+ declare type InferSchemaOutput<ResponseSchema extends StandardSchemaV1> = ResponseSchema extends {
186
165
  _def: any;
187
166
  parse: (data: any) => infer T;
188
- }] ? T : StandardSchemaV1.InferOutput<ResponseSchema>;
167
+ } ? T : StandardSchemaV1.InferOutput<ResponseSchema>;
189
168
 
190
169
  export declare class MiddlewareError extends Error implements HttpClientError {
191
170
  readonly name = "MiddlewareError";
@@ -303,13 +282,9 @@ export declare interface RetryOptions {
303
282
 
304
283
  export declare type Schema<T = unknown> = StandardSchemaV1<unknown, T>;
305
284
 
306
- /**
307
- * Request options that automatically infer the response type from the schema.
308
- * This enables seamless schemaOf integration.
309
- */
310
- declare type SchemaInferredRequestOptions<TBody = unknown, TParams extends RequestParamsType = RequestParamsType, Path extends string = string> = RequirePathParams<Path, Omit<RequestOptions<TBody>, 'params'> & {
285
+ declare type SchemaInferredRequestOptions<TBody = unknown, TResponse = unknown, TParams extends RequestParamsType = RequestParamsType, Path extends string = string> = RequirePathParams<Path, Omit<RequestOptions<TBody>, 'params'> & {
311
286
  params?: TParams;
312
- schema: Schema<any>;
287
+ schema: Schema<TResponse>;
313
288
  }>;
314
289
 
315
290
  export declare class SchemaValidationError extends Error implements HttpClientError {
@@ -352,6 +327,10 @@ export declare class SerializationError extends Error implements HttpClientError
352
327
  constructor(message: string, cause?: Error);
353
328
  }
354
329
 
330
+ declare type SerializeBody<TBody = unknown> = (body: TBody) => BodyInit | null | undefined;
331
+
332
+ declare type SerializeParams = (params: RequestParamsType) => string;
333
+
355
334
  /**
356
335
  * Strips host and optional port from URL, keeping only the path
357
336
  * Handles cases like "localhost:3000/users" -> "/users"
package/dist/index.es.js CHANGED
@@ -174,14 +174,18 @@ async function toStreamableRequest(request, onUploadStreaming) {
174
174
  }
175
175
  const reader = request.body.getReader();
176
176
  const totalBytes = request.headers.get("content-length") ? parseInt(request.headers.get("content-length") || "0", 10) : 0;
177
- const stream = createStreamingStream(reader, (chunk, totalBytes2, transferredBytes) => {
178
- onUploadStreaming({
179
- chunk,
180
- totalBytes: totalBytes2,
181
- // Safe cast since we pass 0 as default
182
- transferredBytes
183
- });
184
- }, totalBytes);
177
+ const stream = createStreamingStream(
178
+ reader,
179
+ (chunk, totalBytes2, transferredBytes) => {
180
+ onUploadStreaming({
181
+ chunk,
182
+ totalBytes: totalBytes2,
183
+ // Safe cast since we pass 0 as default
184
+ transferredBytes
185
+ });
186
+ },
187
+ totalBytes
188
+ );
185
189
  return new Request(request.url, {
186
190
  method: request.method,
187
191
  headers: request.headers,
@@ -204,13 +208,17 @@ async function toStreamableResponse(response, onDownloadStreaming) {
204
208
  }
205
209
  const reader = response.body.getReader();
206
210
  const totalBytes = response.headers.get("content-length") ? parseInt(response.headers.get("content-length") || "0", 10) : void 0;
207
- const stream = createStreamingStream(reader, (chunk, totalBytes2, transferredBytes) => {
208
- onDownloadStreaming({
209
- chunk,
210
- totalBytes: totalBytes2,
211
- transferredBytes
212
- });
213
- }, totalBytes);
211
+ const stream = createStreamingStream(
212
+ reader,
213
+ (chunk, totalBytes2, transferredBytes) => {
214
+ onDownloadStreaming({
215
+ chunk,
216
+ totalBytes: totalBytes2,
217
+ transferredBytes
218
+ });
219
+ },
220
+ totalBytes
221
+ );
214
222
  return new Response(stream, {
215
223
  status: response.status,
216
224
  statusText: response.statusText,
@@ -232,6 +240,9 @@ function createHttpRequest(config = {}) {
232
240
  headers: defaultHeaders = {},
233
241
  timeout: defaultTimeout = 3e4,
234
242
  schemaValidator = createSchemaValidator(),
243
+ fetch: customFetch = fetch,
244
+ serializeBody: customSerializeBody,
245
+ serializeParams: customSerializeParams,
235
246
  onRequestMiddleware,
236
247
  onResponseMiddleware
237
248
  } = config;
@@ -283,11 +294,13 @@ function createHttpRequest(config = {}) {
283
294
  }
284
295
  if (requestContext.params) {
285
296
  const urlObj = new URL(requestContext.url);
286
- Object.entries(requestContext.params).forEach(([key, value]) => {
287
- if (value != null) {
288
- urlObj.searchParams.set(key, String(value));
289
- }
290
- });
297
+ const serializedParams = customSerializeParams ? customSerializeParams(requestContext.params) : new URLSearchParams(
298
+ JSON.parse(JSON.stringify(requestContext.params))
299
+ ).toString();
300
+ if (serializedParams) {
301
+ const queryString = customSerializeParams && serializedParams.startsWith("?") ? serializedParams.slice(1) : serializedParams;
302
+ urlObj.search = queryString;
303
+ }
291
304
  requestContext.url = urlObj.toString();
292
305
  }
293
306
  const requestInit = {
@@ -295,8 +308,24 @@ function createHttpRequest(config = {}) {
295
308
  headers: requestContext.headers,
296
309
  ...requestContext.fetchOptions
297
310
  };
298
- if (requestContext.body !== void 0 && ["POST", "PUT", "PATCH"].includes(requestContext.method)) {
299
- const { body: body2, contentType } = serializeRequestBody(requestContext.body);
311
+ if (requestContext.body !== void 0 && (requestContext.method === "POST" || requestContext.method === "PUT" || requestContext.method === "PATCH")) {
312
+ let body2;
313
+ let contentType;
314
+ if (customSerializeBody) {
315
+ const serializedBody = customSerializeBody(requestContext.body);
316
+ if (serializedBody == null) {
317
+ body2 = "";
318
+ } else {
319
+ body2 = serializedBody;
320
+ if (isObjectLike(requestContext.body) && typeof serializedBody === "string" && !requestContext.headers.has("content-type")) {
321
+ contentType = "application/json";
322
+ }
323
+ }
324
+ } else {
325
+ const serialized = serializeRequestBody(requestContext.body);
326
+ body2 = serialized.body;
327
+ contentType = serialized.contentType;
328
+ }
300
329
  requestInit.body = body2;
301
330
  if (contentType) {
302
331
  requestContext.headers.set("content-type", contentType);
@@ -329,7 +358,7 @@ function createHttpRequest(config = {}) {
329
358
  try {
330
359
  const request = new Request(requestContext.url, requestInit);
331
360
  const trackedRequest = onUploadStreaming ? await toStreamableRequest(request, onUploadStreaming) : request;
332
- const response = await fetch(trackedRequest.url, {
361
+ const response = await customFetch(trackedRequest.url, {
333
362
  method: trackedRequest.method,
334
363
  headers: trackedRequest.headers,
335
364
  body: trackedRequest.body,
@@ -470,17 +499,20 @@ function calculateRetryDelay(attempt, retryOptions) {
470
499
  const delay = baseDelay * Math.pow(backoffFactor, attempt);
471
500
  return Math.min(delay, maxDelay);
472
501
  }
502
+ function isObjectLike(value) {
503
+ return value && typeof value === "object" && value.constructor?.name === "Object" || Array.isArray(value) || typeof value?.toJSON === "function";
504
+ }
473
505
  function serializeRequestBody(body) {
474
506
  if (typeof body === "string" || body instanceof FormData || body instanceof URLSearchParams || body instanceof ArrayBuffer || body instanceof Blob || body instanceof ReadableStream) {
475
507
  return { body };
476
508
  }
477
- if (body !== null && body !== void 0) {
509
+ if (isObjectLike(body)) {
478
510
  return {
479
511
  body: JSON.stringify(body),
480
512
  contentType: "application/json"
481
513
  };
482
514
  }
483
- return { body: "" };
515
+ return { body };
484
516
  }
485
517
  function createErrorMessage(context, error) {
486
518
  return `${context}: ${error instanceof Error ? error.message : String(error)}`;
@@ -577,7 +609,6 @@ export {
577
609
  SerializationError,
578
610
  TimeoutError,
579
611
  createHttpClient,
580
- createSchemaValidator,
581
612
  http as default,
582
613
  http
583
614
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/errors.ts","../src/schema.ts","../src/utils/path.ts","../src/utils/streaming.ts","../src/core.ts","../src/client.ts"],"sourcesContent":["interface HttpClientError {\n name: string\n message: string\n cause?: Error\n stack?: string\n}\n\nexport class HttpError<TErrorData = unknown>\n extends Error\n implements HttpClientError\n{\n public readonly name = 'HttpError'\n public readonly status: number\n public readonly statusText: string\n public readonly data: TErrorData\n public readonly response: Response\n public readonly url: string\n public readonly method: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n data: TErrorData,\n response: Response,\n url: string,\n method: string,\n cause?: Error\n ) {\n const enhancedMessage = `HTTP ${status} ${statusText}: ${message} (${method} ${url})`\n super(enhancedMessage, { cause })\n this.status = status\n this.statusText = statusText\n this.data = data\n this.response = response\n this.url = url\n this.method = method\n }\n}\n\nexport class NetworkError extends Error implements HttpClientError {\n public readonly name = 'NetworkError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class SchemaValidationError extends Error implements HttpClientError {\n public readonly name = 'SchemaValidationError'\n public readonly schema: unknown\n public readonly data: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, data: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.data = data\n }\n}\n\nexport class TimeoutError extends Error implements HttpClientError {\n public readonly name = 'TimeoutError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class PathParameterError extends Error implements HttpClientError {\n public readonly name = 'PathParameterError'\n public readonly url: string\n public readonly requiredParams: string[]\n public readonly providedParams: string[]\n public override readonly cause?: Error\n\n constructor(\n message: string,\n url: string,\n requiredParams: string[],\n providedParams: string[],\n cause?: Error\n ) {\n super(message, { cause })\n this.url = url\n this.requiredParams = requiredParams\n this.providedParams = providedParams\n }\n}\n\nexport class MiddlewareError extends Error implements HttpClientError {\n public readonly name = 'MiddlewareError'\n public readonly interceptorType: 'request' | 'response'\n public readonly url?: string\n public readonly method?: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n interceptorType: 'request' | 'response',\n url?: string,\n method?: string,\n cause?: Error\n ) {\n super(message, { cause })\n this.interceptorType = interceptorType\n this.url = url\n this.method = method\n }\n}\n\nexport class SerializationError extends Error implements HttpClientError {\n public readonly name = 'SerializationError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class InvalidSchemaError extends Error implements HttpClientError {\n public readonly name = 'InvalidSchemaError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class AsyncSchemaValidationError\n extends Error\n implements HttpClientError\n{\n public readonly name = 'AsyncSchemaValidationError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class InvalidBaseUrlError extends Error implements HttpClientError {\n public readonly name = 'InvalidBaseUrlError'\n public readonly baseUrl: string\n public override readonly cause?: Error\n\n constructor(message: string, baseUrl: string, cause?: Error) {\n super(message, { cause })\n this.baseUrl = baseUrl\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport {\n AsyncSchemaValidationError,\n InvalidSchemaError,\n SchemaValidationError,\n} from './errors'\nimport { Schema } from './types'\n\n/**\n * Type guard to check if an object conforms to the Standard Schema V1 specification\n */\nfunction isStandardSchema(obj: unknown): obj is StandardSchemaV1 {\n return (\n obj !== null &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n '~standard' in obj &&\n typeof obj['~standard'] === 'object' &&\n obj['~standard'] !== null &&\n 'validate' in obj['~standard'] &&\n typeof obj['~standard'].validate === 'function' &&\n 'version' in obj['~standard'] &&\n typeof obj['~standard'].version === 'number' &&\n 'vendor' in obj['~standard'] &&\n typeof obj['~standard'].vendor === 'string'\n )\n}\n\n/**\n * Interface for schema validators that can validate data against schemas.\n *\n * This interface allows you to create custom schema validators that work\n * with different validation libraries (Zod, Valibot, Arktype, etc.).\n */\nexport interface SchemaValidator {\n /**\n * Validate data against a schema.\n *\n * @template T - The expected type after validation\n * @param schema - The schema to validate against\n * @param data - The data to validate\n * @returns The validated data with the correct type\n * @throws {SchemaValidationError} If the data doesn't match the schema\n */\n validate<T>(schema: Schema<T>, data: unknown): T\n\n /**\n * Check if an object is a valid schema.\n *\n * @param obj - The object to check\n * @returns True if the object is a valid schema, false otherwise\n */\n isSchema(obj: unknown): boolean\n}\n\n/**\n * Create a default schema validator that supports Standard Schema.\n *\n * This validator only works with schemas that implement the Standard Schema\n * interface. For full support of Zod, Valibot, and Arktype, use the\n * appropriate validator from their respective packages.\n *\n * @returns A schema validator instance\n *\n * @example\n * ```ts\n * import { createSchemaValidator } from '1000fetches'\n *\n * const validator = createSchemaValidator();\n *\n * // Use with HttpClient\n * const client = new HttpClient({\n * schemaValidator: validator\n * });\n * ```\n */\nexport function createSchemaValidator(): SchemaValidator {\n return {\n validate<T>(schema: Schema<T>, data: unknown): T {\n if (!isStandardSchema(schema)) {\n throw new InvalidSchemaError(\n 'Schema must implement the Standard Schema interface',\n schema\n )\n }\n\n const result = schema['~standard'].validate(data)\n\n if (result instanceof Promise) {\n throw new AsyncSchemaValidationError(\n 'Async Standard Schema validation is not supported in this context',\n schema\n )\n }\n\n if (result.issues) {\n throw new SchemaValidationError(\n JSON.stringify(result.issues),\n schema,\n data\n )\n }\n\n return result.value as T\n },\n\n isSchema(obj: unknown): boolean {\n return isStandardSchema(obj)\n },\n }\n}\n","import { PathParameterError } from '../errors'\n\n/**\n * Strips protocol from URL (e.g., https://, http://)\n */\ntype StripProtocol<T extends string> = T extends `${string}://${infer After}`\n ? After\n : T\n\n/**\n * Strips host and optional port from URL, keeping only the path\n * Handles cases like \"localhost:3000/users\" -> \"/users\"\n */\ntype StripHost<T extends string> = T extends `${infer _Host}/${infer Path}`\n ? `/${Path}`\n : T\n\n/**\n * Strips query string from path (e.g., \"/users?x=1\" -> \"/users\")\n * Only strips ? that comes after the path, not ? that's part of path parameters\n */\ntype StripQuery<T extends string> = T extends `${infer Path}?${infer Query}`\n ? Query extends\n | `${string}=${string}`\n | `${string}=${string}&${string}`\n | `${string}&${string}`\n ? Path // contains = or &\n : Query extends `/${string}`\n ? T // it's another path segment\n : Query extends ``\n ? T // it's an optional param marker\n : Path // plain query params like ?param\n : T\n\n/**\n * Normalizes URL to path only, stripping protocol, host, port, and query\n */\ntype NormalizePath<T extends string> = StripQuery<StripHost<StripProtocol<T>>>\n\n/**\n * Removes optional suffix from param name (e.g., \":id?\" -> \"id\", \":id\" -> \"id\")\n */\ntype CleanParamName<S extends string> = S extends `:${infer Name}?`\n ? Name\n : S extends `:${infer Name}`\n ? Name\n : S\n\n/**\n * Extracts all path parameters from a route\n */\nexport type ExtractRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? CleanParamName<`:${Param}`> | ExtractRouteParams<`/${Rest}`>\n : CleanParamName<`:${AfterColon}`>\n : never\n\nexport type HasRequiredParams<T extends string> = [\n ExtractRouteParams<T>,\n] extends [never]\n ? false\n : true\n\n/**\n * PathParams type - extracts parameter names and their types\n */\nexport type PathParams<Path extends string> = {\n [K in ExtractRouteParams<Path>]: string | number\n}\n\n/**\n * RequirePathParams enforces pathParams when needed\n */\nexport type RequirePathParams<Path extends string, T> =\n HasRequiredParams<Path> extends true\n ? T & { pathParams: PathParams<Path> }\n : T\n\n/**\n * Interpolates parameters into a URL template\n * Similar to React Router's generatePath function\n *\n * @example\n * ```ts\n * const path = generatePath('/users/:id/posts/:postId', { id: '123', postId: '456' });\n * // => '/users/123/posts/456'\n * ```\n */\nexport function generatePath<Path extends string>(\n path: Path,\n params: PathParams<Path> = {} as PathParams<Path>\n): string {\n return path.replace(/:([a-zA-Z0-9_]+)/g, (_match, paramName: string) => {\n if (params[paramName as keyof PathParams<Path>] === undefined) {\n throw new PathParameterError(\n `Missing required path parameter: ${paramName}`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n return String(params[paramName as keyof PathParams<Path>])\n })\n}\n","import type { DownloadStreamingEvent, UploadStreamingEvent } from '../types'\n\nfunction createStreamingStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onChunk: (chunk: Uint8Array, totalBytes: number | undefined, transferredBytes: number) => void,\n totalBytes: number | undefined\n): ReadableStream<Uint8Array> {\n let transferredBytes = 0\n\n return new ReadableStream({\n async start(controller) {\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n transferredBytes += value.length\n onChunk(value, totalBytes, transferredBytes)\n controller.enqueue(value)\n }\n } finally {\n reader.releaseLock()\n controller.close()\n }\n },\n })\n}\n\n/**\n * Creates a request with upload streaming tracking\n */\nexport async function toStreamableRequest(\n request: Request,\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n): Promise<Request> {\n if (!onUploadStreaming || !request.body) {\n return request\n }\n\n const reader = request.body.getReader()\n const totalBytes = request.headers.get('content-length')\n ? parseInt(request.headers.get('content-length') || '0', 10)\n : 0\n\n const stream = createStreamingStream(reader, (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes: totalBytes as number, // Safe cast since we pass 0 as default\n transferredBytes,\n })\n }, totalBytes)\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n signal: request.signal,\n credentials: request.credentials,\n cache: request.cache,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n integrity: request.integrity,\n keepalive: request.keepalive,\n duplex: 'half',\n } as RequestInit)\n}\n\n/**\n * Creates a response with download streaming tracking\n */\nexport async function toStreamableResponse(\n response: Response,\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n): Promise<Response> {\n if (!onDownloadStreaming || !response.body) {\n return response\n }\n\n const reader = response.body.getReader()\n const totalBytes = response.headers.get('content-length')\n ? parseInt(response.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(reader, (chunk, totalBytes, transferredBytes) => {\n onDownloadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n }, totalBytes)\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n}\n","import {\n HttpError,\n MiddlewareError,\n NetworkError,\n SchemaValidationError,\n SerializationError,\n TimeoutError,\n} from './errors'\nimport { createSchemaValidator, type SchemaValidator } from './schema'\nimport type {\n DownloadStreamingEvent,\n HttpMethod,\n RequestContext,\n RequestParamsType,\n ResponseType,\n RetryOptions,\n Schema,\n UploadStreamingEvent,\n} from './types'\nimport {\n generatePath,\n toStreamableRequest,\n toStreamableResponse,\n type PathParams,\n} from './utils'\n\n/**\n * Default retry configuration for HTTP requests\n */\nconst DEFAULT_RETRY_OPTIONS: Required<RetryOptions> = {\n maxRetries: 3,\n retryDelay: 300,\n backoffFactor: 2,\n retryStatusCodes: [429, 500, 502, 503, 504],\n retryNetworkErrors: true,\n maxRetryDelay: 30000,\n shouldRetry: () => true,\n}\n\nexport interface HttpRequestOptions<\n TBody = unknown,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n> {\n /** HTTP method */\n method?: HttpMethod\n /** Request headers */\n headers?: Record<string, string>\n /** Query parameters */\n params?: TParams\n /** Path parameters for URL template */\n pathParams?: Record<string, string | number>\n /** Request body */\n body?: TBody\n /** Response schema for validation */\n schema?: Schema<TResponse>\n /** Custom timeout for this request */\n timeout?: number\n /** AbortSignal for request cancellation */\n signal?: AbortSignal\n /** Fetch options */\n credentials?: RequestCredentials\n cache?: RequestCache\n mode?: RequestMode\n redirect?: RequestRedirect\n /** Upload streaming tracking for this specific request */\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n /** Download streaming tracking for this specific request */\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n /** Custom status validation */\n validateStatus?: (status: number) => boolean\n /** Response type override */\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n /** Retry options for this specific request */\n retryOptions?: RetryOptions\n}\n\nexport interface HttpClientConfig {\n /** Base URL for all requests */\n baseUrl?: string\n /** Default headers */\n headers?: Record<string, string>\n /** Default timeout */\n timeout?: number\n /** Schema validator */\n schemaValidator?: SchemaValidator\n /** Default retry options */\n retryOptions?: RetryOptions\n /** Request middleware - can modify request before sending */\n onRequestMiddleware?: <TBody = unknown>(\n context: RequestContext<TBody>\n ) => RequestContext<TBody> | Promise<RequestContext<TBody>>\n /** Response middleware - can modify response after receiving */\n onResponseMiddleware?: (\n response: ResponseType<unknown>\n ) => ResponseType<unknown> | Promise<ResponseType<unknown>>\n}\n\n/**\n * Creates an HTTP request handler with the given configuration.\n * This is the core function that handles all HTTP requests with retry logic,\n * interceptors, streaming, and schema validation.\n */\nexport function createHttpRequest(config: HttpClientConfig = {}) {\n const {\n baseUrl = '',\n headers: defaultHeaders = {},\n timeout: defaultTimeout = 30_000,\n schemaValidator = createSchemaValidator(),\n onRequestMiddleware,\n onResponseMiddleware,\n } = config\n\n return async function fetcher<\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: HttpRequestOptions<TBody, TResponse, TParams> = {}\n ): Promise<ResponseType<TResponse>> {\n const {\n method = 'GET',\n headers = {},\n params,\n pathParams,\n body,\n schema,\n timeout = defaultTimeout,\n signal,\n credentials,\n cache,\n mode,\n redirect,\n onUploadStreaming,\n onDownloadStreaming,\n validateStatus,\n responseType,\n retryOptions: requestRetryOptions,\n } = options\n\n let resolvedUrl = generatePath(url, pathParams as PathParams<Path>)\n if (baseUrl) {\n resolvedUrl = new URL(resolvedUrl, baseUrl).toString()\n }\n\n let requestContext: RequestContext<TBody> = {\n url: resolvedUrl,\n method,\n params,\n headers: new Headers({ ...defaultHeaders, ...headers }),\n body,\n signal,\n fetchOptions: { credentials, cache, mode, redirect },\n }\n\n if (onRequestMiddleware) {\n try {\n requestContext = await onRequestMiddleware(requestContext)\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Request middleware failed', error),\n 'request',\n requestContext.url,\n requestContext.method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n if (requestContext.params) {\n const urlObj = new URL(requestContext.url)\n Object.entries(requestContext.params).forEach(([key, value]) => {\n if (value != null) {\n urlObj.searchParams.set(key, String(value))\n }\n })\n requestContext.url = urlObj.toString()\n }\n\n const requestInit: RequestInit = {\n method: requestContext.method,\n headers: requestContext.headers,\n ...requestContext.fetchOptions,\n }\n\n if (\n requestContext.body !== undefined &&\n ['POST', 'PUT', 'PATCH'].includes(requestContext.method)\n ) {\n const { body, contentType } = serializeRequestBody(requestContext.body)\n requestInit.body = body\n\n if (contentType) {\n requestContext.headers.set('content-type', contentType)\n }\n\n ;(requestInit as any).duplex = 'half'\n }\n\n const mergedRetryOptions = {\n ...DEFAULT_RETRY_OPTIONS,\n ...config.retryOptions,\n ...requestRetryOptions,\n }\n const maxRetries = mergedRetryOptions.maxRetries\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const finalSignal = requestContext.signal\n ? (() => {\n if (requestContext.signal && requestContext.signal.aborted) {\n return requestContext.signal\n }\n\n const combinedController = new AbortController()\n const cleanup = () => {\n clearTimeout(timeoutId)\n combinedController.abort()\n }\n\n requestContext.signal?.addEventListener('abort', cleanup)\n controller.signal.addEventListener('abort', cleanup)\n\n return combinedController.signal\n })()\n : controller.signal\n\n try {\n const request = new Request(requestContext.url, requestInit)\n const trackedRequest = onUploadStreaming\n ? await toStreamableRequest(request, onUploadStreaming)\n : request\n\n const response = await fetch(trackedRequest.url, {\n method: trackedRequest.method,\n headers: trackedRequest.headers,\n body: trackedRequest.body,\n signal: finalSignal,\n ...requestContext.fetchOptions,\n ...(trackedRequest.body && { duplex: 'half' as const }),\n })\n\n const trackedResponse = onDownloadStreaming\n ? await toStreamableResponse(response, onDownloadStreaming)\n : response\n\n const responseData = await processResponse<TResponse>(\n trackedResponse,\n {\n validateStatus,\n schema,\n responseType,\n },\n method,\n requestContext.url,\n schemaValidator\n )\n\n if (onResponseMiddleware) {\n try {\n return (await onResponseMiddleware(\n responseData\n )) as ResponseType<TResponse>\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Response middleware failed', error),\n 'response',\n requestContext.url,\n method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseData\n } catch (error) {\n clearTimeout(timeoutId)\n lastError = error instanceof Error ? error : new Error(String(error))\n\n if (lastError.name === 'AbortError') {\n lastError = new TimeoutError(\n `Request timeout after ${timeout}ms`,\n lastError\n )\n }\n\n if (\n attempt < maxRetries &&\n (await shouldRetry(lastError, attempt, mergedRetryOptions))\n ) {\n const delay = calculateRetryDelay(attempt, mergedRetryOptions)\n await sleep(delay)\n continue\n }\n\n throw lastError\n }\n }\n\n throw lastError || new Error('Request failed')\n }\n}\n\n/**\n * Helper function to process response (extracted from HttpClient)\n */\nasync function processResponse<T>(\n response: Response,\n options: {\n validateStatus?: (status: number) => boolean\n schema?: Schema<T>\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n },\n method: HttpMethod,\n url: string,\n schemaValidator: SchemaValidator\n): Promise<ResponseType<T>> {\n const headers = Object.fromEntries(response.headers.entries())\n\n const validateStatus =\n options.validateStatus ||\n ((status: number) => status >= 200 && status < 300)\n\n let data: unknown\n try {\n if (options.responseType === 'text') {\n data = await response.text()\n } else if (options.responseType === 'blob') {\n data = await response.blob()\n } else if (options.responseType === 'arrayBuffer') {\n data = await response.arrayBuffer()\n } else {\n const contentType = response.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n data = await response.json()\n } else if (contentType?.includes('text/')) {\n data = await response.text()\n } else {\n data = await response.arrayBuffer()\n }\n }\n } catch (error) {\n throw new SerializationError(\n createErrorMessage('Failed to parse response body', error),\n error instanceof Error ? error : undefined\n )\n }\n\n if (!validateStatus(response.status)) {\n throw new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n data,\n response,\n url,\n method\n )\n }\n\n const responseObj: ResponseType<T> = {\n data: data as T,\n status: response.status,\n statusText: response.statusText,\n headers,\n method,\n url,\n raw: response,\n }\n\n if (options.schema) {\n try {\n responseObj.data = schemaValidator.validate(\n options.schema,\n responseObj.data\n ) as T\n } catch (error) {\n throw new SchemaValidationError(\n `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`,\n options.schema,\n responseObj.data,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseObj\n}\n\n/**\n * Determines if a request should be retried based on error type and retry configuration\n */\nasync function shouldRetry(\n error: Error,\n retryCount: number,\n retryOptions?: RetryOptions\n): Promise<boolean> {\n if (!retryOptions) return false\n\n if (retryOptions.shouldRetry) {\n return await retryOptions.shouldRetry(error, retryCount)\n }\n\n if (error instanceof HttpError) {\n return retryOptions.retryStatusCodes?.includes(error.status) ?? false\n }\n\n if (error instanceof NetworkError || error.name === 'TypeError') {\n return retryOptions.retryNetworkErrors ?? false\n }\n\n return false\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n */\nfunction calculateRetryDelay(\n attempt: number,\n retryOptions?: RetryOptions\n): number {\n if (!retryOptions) return 0\n\n const baseDelay = retryOptions.retryDelay ?? 300\n const backoffFactor = retryOptions.backoffFactor ?? 2\n const maxDelay = retryOptions.maxRetryDelay ?? 30000\n\n const delay = baseDelay * Math.pow(backoffFactor, attempt)\n return Math.min(delay, maxDelay)\n}\n\n\n\n/**\n * Serializes request body based on type\n */\nfunction serializeRequestBody(body: unknown): { body: BodyInit; contentType?: string } {\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof ArrayBuffer ||\n body instanceof Blob ||\n body instanceof ReadableStream\n ) {\n return { body: body as BodyInit }\n }\n\n if (body !== null && body !== undefined) {\n return {\n body: JSON.stringify(body),\n contentType: 'application/json'\n }\n }\n\n return { body: '' }\n}\n\n/**\n * Creates a standardized error message\n */\nfunction createErrorMessage(context: string, error: unknown): string {\n return `${context}: ${error instanceof Error ? error.message : String(error)}`\n}\n\n/**\n * Creates a promise that resolves after the specified delay\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n","import type { HttpClientConfig, HttpRequestOptions } from './core'\nimport { createHttpRequest } from './core'\nimport { InvalidBaseUrlError } from './errors'\nimport type {\n EnforcedPathParamsOptions,\n InferSchemaOutput,\n RequestParamsType,\n ResponseType,\n Schema,\n SchemaInferredRequestOptions,\n} from './types'\nimport type { HasRequiredParams } from './utils'\n\nfunction validateAndNormalizeBaseUrl(baseUrl?: string): string {\n const hasLocation =\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined' &&\n window.location.origin !== 'null'\n\n if (!baseUrl) {\n // In browser environment, default to location.origin for relative paths\n return hasLocation ? window.location.origin : ''\n }\n\n if (baseUrl.startsWith('/')) {\n // In Node.js or non-browser environments, relative paths are preserved as-is\n return hasLocation\n ? new URL(baseUrl, window.location.origin).href.replace(/\\/$/, '')\n : baseUrl.replace(/\\/$/, '')\n }\n\n try {\n new URL(baseUrl)\n } catch {\n throw new InvalidBaseUrlError(\n `Invalid baseUrl: \"${baseUrl}\". Must be a valid absolute URL or relative path starting with \"/\".`,\n baseUrl\n )\n }\n\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n}\n\ntype ResponsePromise<T> = Promise<ResponseType<T>> & {\n data(): Promise<T>\n}\n\n/**\n * Wraps a response promise to add the .data() method\n */\nfunction wrapResponsePromise<T>(\n promise: Promise<ResponseType<T>>\n): ResponsePromise<T> {\n const wrappedPromise = promise as ResponsePromise<T>\n wrappedPromise.data = async () => {\n const response = await promise\n return response.data\n }\n return wrappedPromise\n}\n\n/**\n * Creates a complete HTTP client with method builders\n */\nexport function createHttpClient(config: HttpClientConfig = {}) {\n const validatedConfig = {\n ...config,\n baseUrl: validateAndNormalizeBaseUrl(config.baseUrl),\n }\n\n const requestHandler = createHttpRequest(validatedConfig)\n\n function get<\n ResponseSchema extends Schema,\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: SchemaInferredRequestOptions<never, TParams, Path> & {\n schema: ResponseSchema\n }\n ): ResponsePromise<InferSchemaOutput<ResponseSchema>>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ): ResponsePromise<TResponse>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(url: Path, ...args: any[]) {\n return wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'GET',\n })\n )\n }\n\n return {\n get,\n\n post: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'POST',\n body,\n })\n ),\n\n put: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PUT',\n body,\n })\n ),\n\n patch: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PATCH',\n body,\n })\n ),\n\n delete: <\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'DELETE',\n })\n ),\n\n /**\n * Generic request method for custom HTTP methods and full control\n * Similar to native fetch but with 1000fetches features\n */\n request: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options?: HttpRequestOptions<TBody, TResponse, TParams>\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, options)\n ),\n }\n}\n\nexport const http = createHttpClient()\n"],"names":["totalBytes","body"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/errors.ts","../src/schema.ts","../src/utils/path.ts","../src/utils/streaming.ts","../src/core.ts","../src/client.ts"],"sourcesContent":["interface HttpClientError {\n name: string\n message: string\n cause?: Error\n stack?: string\n}\n\nexport class HttpError<TErrorData = unknown>\n extends Error\n implements HttpClientError\n{\n public readonly name = 'HttpError'\n public readonly status: number\n public readonly statusText: string\n public readonly data: TErrorData\n public readonly response: Response\n public readonly url: string\n public readonly method: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n status: number,\n statusText: string,\n data: TErrorData,\n response: Response,\n url: string,\n method: string,\n cause?: Error\n ) {\n const enhancedMessage = `HTTP ${status} ${statusText}: ${message} (${method} ${url})`\n super(enhancedMessage, { cause })\n this.status = status\n this.statusText = statusText\n this.data = data\n this.response = response\n this.url = url\n this.method = method\n }\n}\n\nexport class NetworkError extends Error implements HttpClientError {\n public readonly name = 'NetworkError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class SchemaValidationError extends Error implements HttpClientError {\n public readonly name = 'SchemaValidationError'\n public readonly schema: unknown\n public readonly data: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, data: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n this.data = data\n }\n}\n\nexport class TimeoutError extends Error implements HttpClientError {\n public readonly name = 'TimeoutError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class PathParameterError extends Error implements HttpClientError {\n public readonly name = 'PathParameterError'\n public readonly url: string\n public readonly requiredParams: string[]\n public readonly providedParams: string[]\n public override readonly cause?: Error\n\n constructor(\n message: string,\n url: string,\n requiredParams: string[],\n providedParams: string[],\n cause?: Error\n ) {\n super(message, { cause })\n this.url = url\n this.requiredParams = requiredParams\n this.providedParams = providedParams\n }\n}\n\nexport class MiddlewareError extends Error implements HttpClientError {\n public readonly name = 'MiddlewareError'\n public readonly interceptorType: 'request' | 'response'\n public readonly url?: string\n public readonly method?: string\n public override readonly cause?: Error\n\n constructor(\n message: string,\n interceptorType: 'request' | 'response',\n url?: string,\n method?: string,\n cause?: Error\n ) {\n super(message, { cause })\n this.interceptorType = interceptorType\n this.url = url\n this.method = method\n }\n}\n\nexport class SerializationError extends Error implements HttpClientError {\n public readonly name = 'SerializationError'\n public override readonly cause?: Error\n\n constructor(message: string, cause?: Error) {\n super(message, { cause })\n }\n}\n\nexport class InvalidSchemaError extends Error implements HttpClientError {\n public readonly name = 'InvalidSchemaError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class AsyncSchemaValidationError\n extends Error\n implements HttpClientError\n{\n public readonly name = 'AsyncSchemaValidationError'\n public readonly schema: unknown\n public override readonly cause?: Error\n\n constructor(message: string, schema: unknown, cause?: Error) {\n super(message, { cause })\n this.schema = schema\n }\n}\n\nexport class InvalidBaseUrlError extends Error implements HttpClientError {\n public readonly name = 'InvalidBaseUrlError'\n public readonly baseUrl: string\n public override readonly cause?: Error\n\n constructor(message: string, baseUrl: string, cause?: Error) {\n super(message, { cause })\n this.baseUrl = baseUrl\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport {\n AsyncSchemaValidationError,\n InvalidSchemaError,\n SchemaValidationError,\n} from './errors'\nimport { Schema } from './types'\n\n/**\n * Type guard to check if an object conforms to the Standard Schema V1 specification\n */\nfunction isStandardSchema(obj: unknown): obj is StandardSchemaV1 {\n return (\n obj !== null &&\n (typeof obj === 'object' || typeof obj === 'function') &&\n '~standard' in obj &&\n typeof obj['~standard'] === 'object' &&\n obj['~standard'] !== null &&\n 'validate' in obj['~standard'] &&\n typeof obj['~standard'].validate === 'function' &&\n 'version' in obj['~standard'] &&\n typeof obj['~standard'].version === 'number' &&\n 'vendor' in obj['~standard'] &&\n typeof obj['~standard'].vendor === 'string'\n )\n}\n\n/**\n * Interface for schema validators that can validate data against schemas.\n *\n * This interface allows you to create custom schema validators that work\n * with different validation libraries (Zod, Valibot, Arktype, etc.).\n */\nexport interface SchemaValidator {\n /**\n * Validate data against a schema.\n *\n * @template T - The expected type after validation\n * @param schema - The schema to validate against\n * @param data - The data to validate\n * @returns The validated data with the correct type\n * @throws {SchemaValidationError} If the data doesn't match the schema\n */\n validate<T>(schema: Schema<T>, data: unknown): T\n\n /**\n * Check if an object is a valid schema.\n *\n * @param obj - The object to check\n * @returns True if the object is a valid schema, false otherwise\n */\n isSchema(obj: unknown): boolean\n}\n\n/**\n * Create a default schema validator that supports Standard Schema.\n *\n * This validator only works with schemas that implement the Standard Schema\n * interface. For full support of Zod, Valibot, and Arktype, use the\n * appropriate validator from their respective packages.\n *\n * @returns A schema validator instance\n *\n * @example\n * ```ts\n * import { createSchemaValidator } from '1000fetches'\n *\n * const validator = createSchemaValidator();\n *\n * // Use with HttpClient\n * const client = new HttpClient({\n * schemaValidator: validator\n * });\n * ```\n */\nexport function createSchemaValidator(): SchemaValidator {\n return {\n validate<T>(schema: Schema<T>, data: unknown): T {\n if (!isStandardSchema(schema)) {\n throw new InvalidSchemaError(\n 'Schema must implement the Standard Schema interface',\n schema\n )\n }\n\n const result = schema['~standard'].validate(data)\n\n if (result instanceof Promise) {\n throw new AsyncSchemaValidationError(\n 'Async Standard Schema validation is not supported in this context',\n schema\n )\n }\n\n if (result.issues) {\n throw new SchemaValidationError(\n JSON.stringify(result.issues),\n schema,\n data\n )\n }\n\n return result.value as T\n },\n\n isSchema(obj: unknown): boolean {\n return isStandardSchema(obj)\n },\n }\n}\n","import { PathParameterError } from '../errors'\n\n/**\n * Strips protocol from URL (e.g., https://, http://)\n */\ntype StripProtocol<T extends string> = T extends `${string}://${infer After}`\n ? After\n : T\n\n/**\n * Strips host and optional port from URL, keeping only the path\n * Handles cases like \"localhost:3000/users\" -> \"/users\"\n */\ntype StripHost<T extends string> = T extends `${infer _Host}/${infer Path}`\n ? `/${Path}`\n : T\n\n/**\n * Strips query string from path (e.g., \"/users?x=1\" -> \"/users\")\n * Only strips ? that comes after the path, not ? that's part of path parameters\n */\ntype StripQuery<T extends string> = T extends `${infer Path}?${infer Query}`\n ? Query extends\n | `${string}=${string}`\n | `${string}=${string}&${string}`\n | `${string}&${string}`\n ? Path // contains = or &\n : Query extends `/${string}`\n ? T // it's another path segment\n : Query extends ``\n ? T // it's an optional param marker\n : Path // plain query params like ?param\n : T\n\n/**\n * Normalizes URL to path only, stripping protocol, host, port, and query\n */\ntype NormalizePath<T extends string> = StripQuery<StripHost<StripProtocol<T>>>\n\n/**\n * Removes optional suffix from param name (e.g., \":id?\" -> \"id\", \":id\" -> \"id\")\n */\ntype CleanParamName<S extends string> = S extends `:${infer Name}?`\n ? Name\n : S extends `:${infer Name}`\n ? Name\n : S\n\n/**\n * Extracts all path parameters from a route\n */\nexport type ExtractRouteParams<T extends string> =\n NormalizePath<T> extends `${infer _Before}:${infer AfterColon}`\n ? AfterColon extends `${infer Param}/${infer Rest}`\n ? CleanParamName<`:${Param}`> | ExtractRouteParams<`/${Rest}`>\n : CleanParamName<`:${AfterColon}`>\n : never\n\nexport type HasRequiredParams<T extends string> = [\n ExtractRouteParams<T>,\n] extends [never]\n ? false\n : true\n\n/**\n * PathParams type - extracts parameter names and their types\n */\nexport type PathParams<Path extends string> = {\n [K in ExtractRouteParams<Path>]: string | number\n}\n\n/**\n * RequirePathParams enforces pathParams when needed\n */\nexport type RequirePathParams<Path extends string, T> =\n HasRequiredParams<Path> extends true\n ? T & { pathParams: PathParams<Path> }\n : T\n\n/**\n * Interpolates parameters into a URL template\n * Similar to React Router's generatePath function\n *\n * @example\n * ```ts\n * const path = generatePath('/users/:id/posts/:postId', { id: '123', postId: '456' });\n * // => '/users/123/posts/456'\n * ```\n */\nexport function generatePath<Path extends string>(\n path: Path,\n params: PathParams<Path> = {} as PathParams<Path>\n): string {\n return path.replace(/:([a-zA-Z0-9_]+)/g, (_match, paramName: string) => {\n if (params[paramName as keyof PathParams<Path>] === undefined) {\n throw new PathParameterError(\n `Missing required path parameter: ${paramName}`,\n path,\n [paramName],\n Object.keys(params)\n )\n }\n return String(params[paramName as keyof PathParams<Path>])\n })\n}\n","import type { DownloadStreamingEvent, UploadStreamingEvent } from '../types'\n\nfunction createStreamingStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onChunk: (\n chunk: Uint8Array,\n totalBytes: number | undefined,\n transferredBytes: number\n ) => void,\n totalBytes: number | undefined\n): ReadableStream<Uint8Array> {\n let transferredBytes = 0\n\n return new ReadableStream({\n async start(controller) {\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n transferredBytes += value.length\n onChunk(value, totalBytes, transferredBytes)\n controller.enqueue(value)\n }\n } finally {\n reader.releaseLock()\n controller.close()\n }\n },\n })\n}\n\n/**\n * Creates a request with upload streaming tracking\n */\nexport async function toStreamableRequest(\n request: Request,\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n): Promise<Request> {\n if (!onUploadStreaming || !request.body) {\n return request\n }\n\n const reader = request.body.getReader()\n const totalBytes = request.headers.get('content-length')\n ? parseInt(request.headers.get('content-length') || '0', 10)\n : 0\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes: totalBytes as number, // Safe cast since we pass 0 as default\n transferredBytes,\n })\n },\n totalBytes\n )\n\n return new Request(request.url, {\n method: request.method,\n headers: request.headers,\n body: stream,\n signal: request.signal,\n credentials: request.credentials,\n cache: request.cache,\n mode: request.mode,\n redirect: request.redirect,\n referrer: request.referrer,\n referrerPolicy: request.referrerPolicy,\n integrity: request.integrity,\n keepalive: request.keepalive,\n duplex: 'half',\n } as RequestInit)\n}\n\n/**\n * Creates a response with download streaming tracking\n */\nexport async function toStreamableResponse(\n response: Response,\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n): Promise<Response> {\n if (!onDownloadStreaming || !response.body) {\n return response\n }\n\n const reader = response.body.getReader()\n const totalBytes = response.headers.get('content-length')\n ? parseInt(response.headers.get('content-length') || '0', 10)\n : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onDownloadStreaming({\n chunk,\n totalBytes,\n transferredBytes,\n })\n },\n totalBytes\n )\n\n return new Response(stream, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n })\n}\n","import {\n HttpError,\n MiddlewareError,\n NetworkError,\n SchemaValidationError,\n SerializationError,\n TimeoutError,\n} from './errors'\nimport { createSchemaValidator, type SchemaValidator } from './schema'\nimport type {\n CustomFetch,\n DownloadStreamingEvent,\n HttpMethod,\n RequestContext,\n RequestParamsType,\n ResponseType,\n RetryOptions,\n Schema,\n SerializeBody,\n SerializeParams,\n UploadStreamingEvent,\n} from './types'\nimport {\n generatePath,\n toStreamableRequest,\n toStreamableResponse,\n type PathParams,\n} from './utils'\n\n/**\n * Default retry configuration for HTTP requests\n */\nconst DEFAULT_RETRY_OPTIONS: Required<RetryOptions> = {\n maxRetries: 3,\n retryDelay: 300,\n backoffFactor: 2,\n retryStatusCodes: [429, 500, 502, 503, 504],\n retryNetworkErrors: true,\n maxRetryDelay: 30000,\n shouldRetry: () => true,\n}\n\nexport interface HttpRequestOptions<\n TBody = unknown,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n> {\n /** HTTP method */\n method?: HttpMethod\n /** Request headers */\n headers?: Record<string, string>\n /** Query parameters */\n params?: TParams\n /** Path parameters for URL template */\n pathParams?: Record<string, string | number>\n /** Request body */\n body?: TBody\n /** Response schema for validation */\n schema?: Schema<TResponse>\n /** Custom timeout for this request */\n timeout?: number\n /** AbortSignal for request cancellation */\n signal?: AbortSignal\n /** Fetch options */\n credentials?: RequestCredentials\n cache?: RequestCache\n mode?: RequestMode\n redirect?: RequestRedirect\n /** Upload streaming tracking for this specific request */\n onUploadStreaming?: (event: UploadStreamingEvent) => void\n /** Download streaming tracking for this specific request */\n onDownloadStreaming?: (event: DownloadStreamingEvent) => void\n /** Custom status validation */\n validateStatus?: (status: number) => boolean\n /** Response type override */\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n /** Retry options for this specific request */\n retryOptions?: RetryOptions\n}\n\nexport interface HttpClientConfig {\n /** Base URL for all requests */\n baseUrl?: string\n /** Default headers */\n headers?: Record<string, string>\n /** Default timeout */\n timeout?: number\n /** Schema validator */\n schemaValidator?: SchemaValidator\n /** Default retry options */\n retryOptions?: RetryOptions\n /** Custom fetch implementation */\n fetch?: CustomFetch\n /** Custom body serializer */\n serializeBody?: SerializeBody\n /** Custom params serializer */\n serializeParams?: SerializeParams\n /** Request middleware - can modify request before sending */\n onRequestMiddleware?: <TBody = unknown>(\n context: RequestContext<TBody>\n ) => RequestContext<TBody> | Promise<RequestContext<TBody>>\n /** Response middleware - can modify response after receiving */\n onResponseMiddleware?: (\n response: ResponseType<unknown>\n ) => ResponseType<unknown> | Promise<ResponseType<unknown>>\n}\n\n/**\n * Creates an HTTP request handler with the given configuration.\n * This is the core function that handles all HTTP requests with retry logic,\n * interceptors, streaming, and schema validation.\n */\nexport function createHttpRequest(config: HttpClientConfig = {}) {\n const {\n baseUrl = '',\n headers: defaultHeaders = {},\n timeout: defaultTimeout = 30_000,\n schemaValidator = createSchemaValidator(),\n fetch: customFetch = fetch,\n serializeBody: customSerializeBody,\n serializeParams: customSerializeParams,\n onRequestMiddleware,\n onResponseMiddleware,\n } = config\n\n return async function fetcher<\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: HttpRequestOptions<TBody, TResponse, TParams> = {}\n ): Promise<ResponseType<TResponse>> {\n const {\n method = 'GET',\n headers = {},\n params,\n pathParams,\n body,\n schema,\n timeout = defaultTimeout,\n signal,\n credentials,\n cache,\n mode,\n redirect,\n onUploadStreaming,\n onDownloadStreaming,\n validateStatus,\n responseType,\n retryOptions: requestRetryOptions,\n } = options\n\n let resolvedUrl = generatePath(url, pathParams as PathParams<Path>)\n if (baseUrl) {\n resolvedUrl = new URL(resolvedUrl, baseUrl).toString()\n }\n\n let requestContext: RequestContext<TBody> = {\n url: resolvedUrl,\n method,\n params,\n headers: new Headers({ ...defaultHeaders, ...headers }),\n body,\n signal,\n fetchOptions: { credentials, cache, mode, redirect },\n }\n\n if (onRequestMiddleware) {\n try {\n requestContext = await onRequestMiddleware(requestContext)\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Request middleware failed', error),\n 'request',\n requestContext.url,\n requestContext.method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n if (requestContext.params) {\n const urlObj = new URL(requestContext.url)\n const serializedParams = customSerializeParams\n ? customSerializeParams(requestContext.params)\n : new URLSearchParams(\n JSON.parse(JSON.stringify(requestContext.params)) as Record<\n string,\n string\n >\n ).toString()\n\n if (serializedParams) {\n const queryString =\n customSerializeParams && serializedParams.startsWith('?')\n ? serializedParams.slice(1)\n : serializedParams\n urlObj.search = queryString\n }\n\n requestContext.url = urlObj.toString()\n }\n\n const requestInit: RequestInit = {\n method: requestContext.method,\n headers: requestContext.headers,\n ...requestContext.fetchOptions,\n }\n\n if (\n requestContext.body !== undefined &&\n (requestContext.method === 'POST' ||\n requestContext.method === 'PUT' ||\n requestContext.method === 'PATCH')\n ) {\n let body: BodyInit\n let contentType: string | undefined\n\n if (customSerializeBody) {\n const serializedBody = customSerializeBody(requestContext.body)\n if (serializedBody == null) {\n body = ''\n } else {\n body = serializedBody\n\n if (\n isObjectLike(requestContext.body) &&\n typeof serializedBody === 'string' &&\n !requestContext.headers.has('content-type')\n ) {\n contentType = 'application/json'\n }\n }\n } else {\n const serialized = serializeRequestBody(requestContext.body)\n body = serialized.body\n contentType = serialized.contentType\n }\n\n requestInit.body = body\n\n if (contentType) {\n requestContext.headers.set('content-type', contentType)\n }\n\n ;(requestInit as any).duplex = 'half'\n }\n\n const mergedRetryOptions = {\n ...DEFAULT_RETRY_OPTIONS,\n ...config.retryOptions,\n ...requestRetryOptions,\n }\n const maxRetries = mergedRetryOptions.maxRetries\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const finalSignal = requestContext.signal\n ? (() => {\n if (requestContext.signal && requestContext.signal.aborted) {\n return requestContext.signal\n }\n\n const combinedController = new AbortController()\n const cleanup = () => {\n clearTimeout(timeoutId)\n combinedController.abort()\n }\n\n requestContext.signal?.addEventListener('abort', cleanup)\n controller.signal.addEventListener('abort', cleanup)\n\n return combinedController.signal\n })()\n : controller.signal\n\n try {\n const request = new Request(requestContext.url, requestInit)\n const trackedRequest = onUploadStreaming\n ? await toStreamableRequest(request, onUploadStreaming)\n : request\n\n const response = await customFetch(trackedRequest.url, {\n method: trackedRequest.method,\n headers: trackedRequest.headers,\n body: trackedRequest.body,\n signal: finalSignal,\n ...requestContext.fetchOptions,\n ...(trackedRequest.body && { duplex: 'half' as const }),\n })\n\n const trackedResponse = onDownloadStreaming\n ? await toStreamableResponse(response, onDownloadStreaming)\n : response\n\n const responseData = await processResponse<TResponse>(\n trackedResponse,\n {\n validateStatus,\n schema,\n responseType,\n },\n method,\n requestContext.url,\n schemaValidator\n )\n\n if (onResponseMiddleware) {\n try {\n return (await onResponseMiddleware(\n responseData\n )) as ResponseType<TResponse>\n } catch (error) {\n throw new MiddlewareError(\n createErrorMessage('Response middleware failed', error),\n 'response',\n requestContext.url,\n method,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseData\n } catch (error) {\n clearTimeout(timeoutId)\n lastError = error instanceof Error ? error : new Error(String(error))\n\n if (lastError.name === 'AbortError') {\n lastError = new TimeoutError(\n `Request timeout after ${timeout}ms`,\n lastError\n )\n }\n\n if (\n attempt < maxRetries &&\n (await shouldRetry(lastError, attempt, mergedRetryOptions))\n ) {\n const delay = calculateRetryDelay(attempt, mergedRetryOptions)\n await sleep(delay)\n continue\n }\n\n throw lastError\n }\n }\n\n throw lastError || new Error('Request failed')\n }\n}\n\n/**\n * Helper function to process response (extracted from HttpClient)\n */\nasync function processResponse<T>(\n response: Response,\n options: {\n validateStatus?: (status: number) => boolean\n schema?: Schema<T>\n responseType?: 'text' | 'blob' | 'arrayBuffer'\n },\n method: HttpMethod,\n url: string,\n schemaValidator: SchemaValidator\n): Promise<ResponseType<T>> {\n const headers = Object.fromEntries(response.headers.entries())\n\n const validateStatus =\n options.validateStatus ||\n ((status: number) => status >= 200 && status < 300)\n\n let data: unknown\n try {\n if (options.responseType === 'text') {\n data = await response.text()\n } else if (options.responseType === 'blob') {\n data = await response.blob()\n } else if (options.responseType === 'arrayBuffer') {\n data = await response.arrayBuffer()\n } else {\n const contentType = response.headers.get('content-type')\n if (contentType?.includes('application/json')) {\n data = await response.json()\n } else if (contentType?.includes('text/')) {\n data = await response.text()\n } else {\n data = await response.arrayBuffer()\n }\n }\n } catch (error) {\n throw new SerializationError(\n createErrorMessage('Failed to parse response body', error),\n error instanceof Error ? error : undefined\n )\n }\n\n if (!validateStatus(response.status)) {\n throw new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n data,\n response,\n url,\n method\n )\n }\n\n const responseObj: ResponseType<T> = {\n data: data as T,\n status: response.status,\n statusText: response.statusText,\n headers,\n method,\n url,\n raw: response,\n }\n\n if (options.schema) {\n try {\n responseObj.data = schemaValidator.validate(\n options.schema,\n responseObj.data\n ) as T\n } catch (error) {\n throw new SchemaValidationError(\n `Schema validation failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n options.schema,\n responseObj.data,\n error instanceof Error ? error : undefined\n )\n }\n }\n\n return responseObj\n}\n\n/**\n * Determines if a request should be retried based on error type and retry configuration\n */\nasync function shouldRetry(\n error: Error,\n retryCount: number,\n retryOptions?: RetryOptions\n): Promise<boolean> {\n if (!retryOptions) return false\n\n if (retryOptions.shouldRetry) {\n return await retryOptions.shouldRetry(error, retryCount)\n }\n\n if (error instanceof HttpError) {\n return retryOptions.retryStatusCodes?.includes(error.status) ?? false\n }\n\n if (error instanceof NetworkError || error.name === 'TypeError') {\n return retryOptions.retryNetworkErrors ?? false\n }\n\n return false\n}\n\n/**\n * Calculates the delay for the next retry attempt using exponential backoff\n */\nfunction calculateRetryDelay(\n attempt: number,\n retryOptions?: RetryOptions\n): number {\n if (!retryOptions) return 0\n\n const baseDelay = retryOptions.retryDelay ?? 300\n const backoffFactor = retryOptions.backoffFactor ?? 2\n const maxDelay = retryOptions.maxRetryDelay ?? 30000\n\n const delay = baseDelay * Math.pow(backoffFactor, attempt)\n return Math.min(delay, maxDelay)\n}\n\n/**\n * Determines if a value should be JSON stringified (same as up-fetch)\n */\nfunction isObjectLike(\n value: any\n): value is Record<string, any> | any[] | { toJSON(): any } {\n return (\n (value &&\n typeof value === 'object' &&\n value.constructor?.name === 'Object') ||\n Array.isArray(value) ||\n typeof value?.toJSON === 'function'\n )\n}\n\n/**\n * Serializes request body based on type (same as up-fetch)\n */\nfunction serializeRequestBody(body: unknown): {\n body: BodyInit\n contentType?: string\n} {\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof ArrayBuffer ||\n body instanceof Blob ||\n body instanceof ReadableStream\n ) {\n return { body: body as BodyInit }\n }\n\n if (isObjectLike(body)) {\n return {\n body: JSON.stringify(body),\n contentType: 'application/json',\n }\n }\n\n return { body: body as BodyInit }\n}\n\n/**\n * Creates a standardized error message\n */\nfunction createErrorMessage(context: string, error: unknown): string {\n return `${context}: ${error instanceof Error ? error.message : String(error)}`\n}\n\n/**\n * Creates a promise that resolves after the specified delay\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n","import type { HttpClientConfig, HttpRequestOptions } from './core'\nimport { createHttpRequest } from './core'\nimport { InvalidBaseUrlError } from './errors'\nimport type {\n EnforcedPathParamsOptions,\n InferSchemaOutput,\n RequestParamsType,\n ResponseType,\n Schema,\n SchemaInferredRequestOptions,\n} from './types'\nimport type { HasRequiredParams } from './utils'\n\nfunction validateAndNormalizeBaseUrl(baseUrl?: string): string {\n const hasLocation =\n typeof window !== 'undefined' &&\n typeof window.location !== 'undefined' &&\n window.location.origin !== 'null'\n\n if (!baseUrl) {\n // In browser environment, default to location.origin for relative paths\n return hasLocation ? window.location.origin : ''\n }\n\n if (baseUrl.startsWith('/')) {\n // In Node.js or non-browser environments, relative paths are preserved as-is\n return hasLocation\n ? new URL(baseUrl, window.location.origin).href.replace(/\\/$/, '')\n : baseUrl.replace(/\\/$/, '')\n }\n\n try {\n new URL(baseUrl)\n } catch {\n throw new InvalidBaseUrlError(\n `Invalid baseUrl: \"${baseUrl}\". Must be a valid absolute URL or relative path starting with \"/\".`,\n baseUrl\n )\n }\n\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n}\n\ntype ResponsePromise<T> = Promise<ResponseType<T>> & {\n data(): Promise<T>\n}\n\n/**\n * Wraps a response promise to add the .data() method\n */\nfunction wrapResponsePromise<T>(\n promise: Promise<ResponseType<T>>\n): ResponsePromise<T> {\n const wrappedPromise = promise as ResponsePromise<T>\n wrappedPromise.data = async () => {\n const response = await promise\n return response.data\n }\n return wrappedPromise\n}\n\n/**\n * Creates a complete HTTP client with method builders\n */\nexport function createHttpClient(config: HttpClientConfig = {}) {\n const validatedConfig = {\n ...config,\n baseUrl: validateAndNormalizeBaseUrl(config.baseUrl),\n }\n\n const requestHandler = createHttpRequest(validatedConfig)\n\n function get<\n ResponseSchema extends Schema,\n Path extends string = string,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options: SchemaInferredRequestOptions<\n never,\n InferSchemaOutput<ResponseSchema>,\n TParams,\n Path\n > & {\n schema: ResponseSchema\n }\n ): ResponsePromise<InferSchemaOutput<ResponseSchema>>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ): ResponsePromise<TResponse>\n\n function get<\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(url: Path, ...args: any[]) {\n return wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'GET',\n })\n )\n }\n\n return {\n get,\n\n post: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'POST',\n body,\n })\n ),\n\n put: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PUT',\n body,\n })\n ),\n\n patch: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n body?: TBody,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<TBody, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, {\n ...args[0],\n method: 'PATCH',\n body,\n })\n ),\n\n delete: <\n Path extends string = string,\n TResponse = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n ...args: HasRequiredParams<Path> extends true\n ? [options: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n : [options?: EnforcedPathParamsOptions<never, TResponse, TParams, Path>]\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, never, TParams>(url, {\n ...args[0],\n method: 'DELETE',\n })\n ),\n\n /**\n * Generic request method for custom HTTP methods and full control\n * Similar to native fetch but with 1000fetches features\n */\n request: <\n Path extends string = string,\n TResponse = unknown,\n TBody = unknown,\n TParams extends RequestParamsType = RequestParamsType,\n >(\n url: Path,\n options?: HttpRequestOptions<TBody, TResponse, TParams>\n ) =>\n wrapResponsePromise(\n requestHandler<Path, TResponse, TBody, TParams>(url, options)\n ),\n }\n}\n\nexport const http = createHttpClient()\n"],"names":["totalBytes","body"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "1000fetches",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "A type-first HTTP client with compile-time path validation, schema validation, middleware, retries, and real-time streaming — powered by native fetch. Supports Zod, Valibot, ArkType, and any Standard Schema-compatible library.",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",