1000fetches 0.1.9 → 0.1.11
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/LICENSE +21 -0
- package/dist/README.md +328 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +16 -3
- package/dist/index.es.js.map +1 -1
- package/package.json +9 -11
package/dist/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Max Tarsis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# 1000fetches
|
|
2
|
+
|
|
3
|
+
_Type-first HTTP client with schema validation, compile-time path safety, and streaming_
|
|
4
|
+
<br/>
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/1000fetches)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
> Built for the 1000th call to be as safe as the first
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### The problem
|
|
13
|
+
|
|
14
|
+
You start with `fetch`, then add a wrapper for error handling.
|
|
15
|
+
Then generics. Then path params. Then retries and timeouts.
|
|
16
|
+
Soon every project grows its own version — slightly different, equally fragile.
|
|
17
|
+
|
|
18
|
+
Alternatives? Tiny helpers that stop halfway,
|
|
19
|
+
or heavy Axios-style clients that add weight without type guarantees.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### The idea
|
|
24
|
+
|
|
25
|
+
A type-first HTTP client that unifies validation, retries, streaming, and middleware on top of native `fetch`.
|
|
26
|
+
<br/>
|
|
27
|
+
No magic, no layers of indirection. Just a single, explicit API that makes every request verifiably safe.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### The claim
|
|
32
|
+
|
|
33
|
+
> Schema-powered Fetch 2.0 — where types meet runtime reality
|
|
34
|
+
|
|
35
|
+
The point where TypeScript inference, runtime validation, and minimal design converge.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### Highlights
|
|
40
|
+
|
|
41
|
+
- 🧭 **Compile-time path safety** — `:pathParam` can't slip through undefined
|
|
42
|
+
- 🧩 **Schema-driven validation** — infer types at build time, verify data at runtime
|
|
43
|
+
- ⚡ **Native streaming** — observe, transform, or pipe data chunks as they flow
|
|
44
|
+
- 🔁 **Retries, timeouts, middleware** — production essentials, zero config
|
|
45
|
+
- 🎯 **Method-based API** — `api.get()`, `api.post()` with `.data()` extractor for clean code
|
|
46
|
+
- 🧠 **Designed for flow** — clear API, predictable behavior, no hidden magic
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install 1000fetches
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { createHttpClient } from '1000fetches'
|
|
57
|
+
import { z } from 'zod'
|
|
58
|
+
|
|
59
|
+
// Create client
|
|
60
|
+
const api = createHttpClient({
|
|
61
|
+
baseUrl: 'https://api.example.com',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// Type-safe request with path params
|
|
65
|
+
const userResponse = await api.get('/users/:id', {
|
|
66
|
+
pathParams: { id: '123' },
|
|
67
|
+
schema: z.object({ name: z.string() }),
|
|
68
|
+
})
|
|
69
|
+
// user.data 👉 { name: string }
|
|
70
|
+
|
|
71
|
+
// Extractor
|
|
72
|
+
const user = await api
|
|
73
|
+
.get('/users/:id', {
|
|
74
|
+
pathParams: { id: '123' },
|
|
75
|
+
schema: z.object({ name: z.string() }),
|
|
76
|
+
})
|
|
77
|
+
.data() // Returns Promise<{ name: string }> directly, skipping the .data property
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Or use the default client for quick requests:**
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import http from '1000fetches'
|
|
84
|
+
|
|
85
|
+
const user = await http.get('/users/:id', {
|
|
86
|
+
pathParams: { id: '123' },
|
|
87
|
+
schema: userSchema,
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## ➡️ Key Features
|
|
92
|
+
|
|
93
|
+
### ✔️ Type Safety That Actually Works
|
|
94
|
+
|
|
95
|
+
- **Compile-time path validation** — TypeScript catches missing `:userId` parameters before runtime
|
|
96
|
+
- **Runtime schema validation** — Schemas verify data at the network boundary
|
|
97
|
+
- **Schema-based type inference** — Types inferred from schemas, no generics needed
|
|
98
|
+
- **Multi-schema support** — [Zod](https://github.com/colinhacks/zod), [Valibot](https://github.com/fabian-hiller/valibot), [ArkType](https://github.com/arktypeio/arktype), or any [Standard Schema](https://github.com/standard-schema/standard-schema)-compatible library
|
|
99
|
+
|
|
100
|
+
### ✔️ Production-Ready Quality
|
|
101
|
+
|
|
102
|
+
- **Smart retry logic** — Exponential backoff with jitter for resilient requests
|
|
103
|
+
- **Timeout and cancellation support** — Built-in `AbortController` integration
|
|
104
|
+
- **Structured error handling** — `HttpError`, `NetworkError`, `TimeoutError` with full context
|
|
105
|
+
- **Request/Response middleware** — Authentication, logging, transformations
|
|
106
|
+
- **Minimalistic footprint** — Enterprise features without the bloat
|
|
107
|
+
|
|
108
|
+
### ✔️ Engineer-Friendly DX
|
|
109
|
+
|
|
110
|
+
- **Method-based API** — `api.get()`, `api.post()` with full type safety
|
|
111
|
+
- **Automatic response parsing** — JSON/text responses parsed automatically
|
|
112
|
+
- **Smart data extraction** — Chain `.data()` for direct value access without `.data` property
|
|
113
|
+
- **Real-time streaming** — Access actual data chunks during upload/download
|
|
114
|
+
- **Zero dependencies** — Optional peer dependencies, tree-shakable builds
|
|
115
|
+
- **TypeScript-first** — Full type inference and `IntelliSense` support
|
|
116
|
+
|
|
117
|
+
**1000fetches** combines native `fetch` performance with enterprise-grade features and bulletproof type safety.
|
|
118
|
+
|
|
119
|
+
## ➡️ Usage Examples
|
|
120
|
+
|
|
121
|
+
### Authentication
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
const api = createHttpClient({
|
|
125
|
+
baseUrl: 'https://api.example.com',
|
|
126
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Or dynamic auth
|
|
130
|
+
const api = createHttpClient({
|
|
131
|
+
baseUrl: 'https://api.example.com',
|
|
132
|
+
onRequestMiddleware: async context => {
|
|
133
|
+
const token = await getToken()
|
|
134
|
+
context.headers.set('Authorization', `Bearer ${token}`)
|
|
135
|
+
return context
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Streaming
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
// Upload progress with actual data chunks
|
|
144
|
+
await api.post('/api/files', fileData, {
|
|
145
|
+
onUploadStreaming: ({ chunk, transferredBytes, totalBytes }) => {
|
|
146
|
+
const progress = Math.round((transferredBytes / totalBytes) * 100)
|
|
147
|
+
console.log(`Uploading: ${progress}% - chunk size: ${chunk.length} bytes`)
|
|
148
|
+
},
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
// Download progress
|
|
152
|
+
await api.get('/api/files/:id', {
|
|
153
|
+
pathParams: { id: '123' },
|
|
154
|
+
onDownloadStreaming: ({ chunk, transferredBytes, totalBytes }) => {
|
|
155
|
+
const progress = Math.round((transferredBytes / totalBytes) * 100)
|
|
156
|
+
console.log(`Downloading: ${progress}% - chunk size: ${chunk.length} bytes`)
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Error Handling
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { HttpError, NetworkError, TimeoutError, MiddlewareError, PathParameterError } from '1000fetches'
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const user = await api.get('/users/:id', {
|
|
168
|
+
pathParams: { id: '123' },
|
|
169
|
+
schema: userSchema,
|
|
170
|
+
})
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error instanceof HttpError) {
|
|
173
|
+
console.log(`HTTP ${error.status}: ${error.statusText}`)
|
|
174
|
+
} else if (error instanceof NetworkError) {
|
|
175
|
+
console.log('Network error:', error.message)
|
|
176
|
+
} else if (error instanceof TimeoutError) {
|
|
177
|
+
console.log('Request timed out')
|
|
178
|
+
} else if (error instanceof MiddlewareError) {
|
|
179
|
+
console.log('Middleware error:', error.message)
|
|
180
|
+
} else if (error instanceof PathParameterError) {
|
|
181
|
+
console.log('Path parameter error:', error.message)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## API Reference
|
|
187
|
+
|
|
188
|
+
### <samp>createHttpClient(config?)</samp>
|
|
189
|
+
|
|
190
|
+
Creates a new HTTP client with optional configuration.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
function createHttpClient(config?: HttpClientConfig): HttpClient
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Configuration Options:**
|
|
197
|
+
|
|
198
|
+
| Option | Type | Description |
|
|
199
|
+
| ----------------------------- | --------------------------------------- | ------------------------------------- |
|
|
200
|
+
| `baseUrl` | `string` | Base URL for all requests |
|
|
201
|
+
| `headers` | `Record<string, string>` | Default headers |
|
|
202
|
+
| `timeout` | `number` | Default timeout in milliseconds |
|
|
203
|
+
| `retryOptions` | `RetryOptions` | Default retry configuration |
|
|
204
|
+
| `onRequestMiddleware` | `(context: RequestContext) => RequestContext` | Request middleware |
|
|
205
|
+
| `onResponseMiddleware` | `(response: ResponseType) => ResponseType` | Response middleware |
|
|
206
|
+
| `schemaValidator` | `SchemaValidator` | Custom schema validator |
|
|
207
|
+
|
|
208
|
+
### <samp>HTTP Methods</samp>
|
|
209
|
+
|
|
210
|
+
All HTTP methods support the same options:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
await api.get('/users/:id', {
|
|
214
|
+
pathParams: { id: '123' },
|
|
215
|
+
schema: userSchema,
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// POST
|
|
219
|
+
await api.post('/users', userData, {
|
|
220
|
+
schema: userSchema,
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
// PUT
|
|
224
|
+
await api.put('/users/:id', userData, {
|
|
225
|
+
pathParams: { id: '123' },
|
|
226
|
+
schema: userSchema,
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// PATCH
|
|
230
|
+
await api.patch('/users/:id', partialData, {
|
|
231
|
+
pathParams: { id: '123' },
|
|
232
|
+
schema: userSchema,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
// DELETE
|
|
236
|
+
await api.delete('/users/:id', {
|
|
237
|
+
pathParams: { id: '123' },
|
|
238
|
+
})
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### <samp>Request Options</samp>
|
|
242
|
+
|
|
243
|
+
| Option | Type | Description |
|
|
244
|
+
| ----------------------------- | --------------------------------------- | ------------------------------------- |
|
|
245
|
+
| `pathParams` | `Record<string, string \| number>` | Path parameters for URL templates |
|
|
246
|
+
| `params` | `Record<string, string \| number \| boolean \| undefined>` | Query parameters |
|
|
247
|
+
| `headers` | `Record<string, string>` | Request headers |
|
|
248
|
+
| `body` | `any` | Request body |
|
|
249
|
+
| `schema` | `Schema` | Response validation schema |
|
|
250
|
+
| `timeout` | `number` | Request timeout |
|
|
251
|
+
| `signal` | `AbortSignal` | Request cancellation signal |
|
|
252
|
+
| `validateStatus` | `(status: number) => boolean` | Custom status validation |
|
|
253
|
+
| `responseType` | `'text' \| 'blob' \| 'arrayBuffer'` | Response type override |
|
|
254
|
+
| `cache` | `RequestCache` | Cache mode |
|
|
255
|
+
| `credentials` | `RequestCredentials` | Credentials mode |
|
|
256
|
+
| `mode` | `RequestMode` | Request mode |
|
|
257
|
+
| `redirect` | `RequestRedirect` | Redirect mode |
|
|
258
|
+
| `retryOptions` | `RetryOptions` | Retry configuration |
|
|
259
|
+
| `onUploadStreaming` | `(event: UploadStreamingEvent) => void` | Upload streaming callback |
|
|
260
|
+
| `onDownloadStreaming` | `(event: DownloadStreamingEvent) => void` | Download streaming callback |
|
|
261
|
+
|
|
262
|
+
### <samp>Response Object</samp>
|
|
263
|
+
|
|
264
|
+
All requests return a `ResponseType<T>` object:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
interface ResponseType<T> {
|
|
268
|
+
data: T // Parsed response data
|
|
269
|
+
status: number // HTTP status code
|
|
270
|
+
statusText: string // HTTP status text
|
|
271
|
+
headers: Record<string, string> // Response headers
|
|
272
|
+
method: HttpMethod // HTTP method used
|
|
273
|
+
url: string // Final URL
|
|
274
|
+
raw: Response // Raw fetch Response
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### <samp>Data Extractor</samp>
|
|
279
|
+
|
|
280
|
+
For convenience, you can extract data directly:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
const user = await api
|
|
284
|
+
.get('/users/:id', {
|
|
285
|
+
pathParams: { id: '123' },
|
|
286
|
+
schema: userSchema,
|
|
287
|
+
})
|
|
288
|
+
.data() // Returns Promise<User> instead of ResponseType<User>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## ➡️ Feature Comparison
|
|
292
|
+
|
|
293
|
+
**1000fetches vs Popular Alternatives**
|
|
294
|
+
|
|
295
|
+
| Feature | 1000fetches | Axios | Better-fetch | Up-fetch | Native Fetch |
|
|
296
|
+
| --------------------- | ----------------- | --------------- | ------------------ | ------------------ | ------------------ |
|
|
297
|
+
| **Bundle Size (gz)** | ≈4.3 kB | ≈14.75 kB | ≈3.07 kB | ≈1.6 kB | 0 kB |
|
|
298
|
+
| **TypeScript** | ✅ Full inference | ⚠️ Limited | ⚠️ Limited | ✅ Good | ❌ Manual |
|
|
299
|
+
| **Path Params** | ✅ Compile-time | ❌ Manual | ❌ Manual | ❌ Manual | ❌ Manual |
|
|
300
|
+
| **Schema Validation** | ✅ Multi-library | ❌ None | ⚠️ Limited | ✅ Multi-library | ❌ None |
|
|
301
|
+
| **Retry Logic** | ✅ Built-in | ✅ Built-in | ❌ Manual | ✅ Built-in | ❌ Manual |
|
|
302
|
+
| **Error Handling** | ✅ Structured | ✅ Good | ⚠️ Basic | ✅ Good | ⚠️ Verbose |
|
|
303
|
+
| **Middleware** | ✅ Full support | ✅ Full support | ⚠️ Limited | ✅ Lifecycle hooks | ❌ None |
|
|
304
|
+
| **Streaming** | ✅ Real chunks | ❌ None | ❌ None | ✅ Real chunks | ✅ Native |
|
|
305
|
+
| **API Design** | ✅ Method-based | ✅ Method-based | ❌ Single function | ❌ Single function | ❌ Single function |
|
|
306
|
+
| **Tree Shaking** | ✅ Good | ⚠️ Partial | ✅ Good | ✅ Perfect | ✅ |
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 📄 License
|
|
311
|
+
|
|
312
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
<div align="center">
|
|
317
|
+
|
|
318
|
+
**Built for developers who believe type safety shouldn't be optional.**
|
|
319
|
+
**Because your backend deserves skepticism.**
|
|
320
|
+
|
|
321
|
+
</div>
|
|
322
|
+
|
|
323
|
+
<!-- Links -->
|
|
324
|
+
|
|
325
|
+
[zod]: https://zod.dev/
|
|
326
|
+
[valibot]: https://valibot.dev/
|
|
327
|
+
[arktype]: https://arktype.dev/
|
|
328
|
+
[standard-schema]: https://github.com/standard-schema/standard-schema
|
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):void 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
|
|
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):void 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 p(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 m={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,v={}){const{method:T="GET",headers:R={},params:P,pathParams:U,body:O,schema:$,timeout:A=o,signal:k,credentials:j,cache:q,mode:B,redirect:L,onUploadStreaming:M,onDownloadStreaming:H,validateStatus:C,responseType:D,retryOptions:N}=v;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:T,params:P,headers:new Headers({...r,...R}),body:O,signal:k,fetchOptions:{credentials:j,cache:q,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):function(e){const t=new URLSearchParams;for(const[r,a]of Object.entries(e))if(Array.isArray(a))for(const e of a)null!=e&&t.append(r,String(e));else null!=a&&t.append(r,String(a));return t.toString()}(I.params);if(t){const r=u&&t.startsWith("?")?t.slice(1):t;e.search=r}I.url=e.toString()}const V={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}V.body=e,t&&I.headers.set("content-type",t),V.duplex="half"}const F={...m,...e.retryOptions,...N},J=F.maxRetries;let W;for(let e=0;e<=J;e+=1){const t=new AbortController,r=setTimeout(()=>t.abort(),A),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,V),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=H?await p(r,H):r,o=await w(a,{validateStatus:C,schema:$,responseType:D},T,I.url,i);if(y)try{return await y(o)}catch(_){throw new n(x("Response middleware failed",_),"response",I.url,T,_ 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 ${A}ms`,W)),e<J&&await b(W,e,F)){const t=g(e,F);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 v(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 R(e={}){const t=y({...e,baseUrl:v(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 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
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -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: (\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 : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes,\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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"}
|
|
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 : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes,\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 : serializeQueryParams(requestContext.params)\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\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\nfunction serializeQueryParams(params: RequestParamsType): string {\n const searchParams = new URLSearchParams()\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item !== undefined && item !== null) {\n searchParams.append(key, String(item))\n }\n }\n } else if (value !== undefined && value !== null) {\n searchParams.append(key, String(value))\n }\n }\n\n return searchParams.toString()\n}\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","searchParams","URLSearchParams","key","entries","Array","isArray","item","append","serializeQueryParams","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","text","blob","arrayBuffer","includes","json","responseObj","raw","retryCount","baseDelay","maxDelay","Math","pow","min","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
|
@@ -243,7 +243,7 @@ export declare interface RequestOptions<TBody = unknown> {
|
|
|
243
243
|
onDownloadStreaming?: (event: DownloadStreamingEvent) => void;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
declare type RequestParamsType = Record<string, string | number | boolean | string[] | undefined>;
|
|
246
|
+
declare type RequestParamsType = Record<string, string | number | boolean | (string | number | boolean | undefined | null)[] | undefined | null>;
|
|
247
247
|
|
|
248
248
|
/**
|
|
249
249
|
* RequirePathParams enforces pathParams when needed
|
package/dist/index.es.js
CHANGED
|
@@ -293,9 +293,7 @@ function createHttpRequest(config = {}) {
|
|
|
293
293
|
}
|
|
294
294
|
if (requestContext.params) {
|
|
295
295
|
const urlObj = new URL(requestContext.url);
|
|
296
|
-
const serializedParams = customSerializeParams ? customSerializeParams(requestContext.params) :
|
|
297
|
-
JSON.parse(JSON.stringify(requestContext.params))
|
|
298
|
-
).toString();
|
|
296
|
+
const serializedParams = customSerializeParams ? customSerializeParams(requestContext.params) : serializeQueryParams(requestContext.params);
|
|
299
297
|
if (serializedParams) {
|
|
300
298
|
const queryString = customSerializeParams && serializedParams.startsWith("?") ? serializedParams.slice(1) : serializedParams;
|
|
301
299
|
urlObj.search = queryString;
|
|
@@ -501,6 +499,21 @@ function calculateRetryDelay(attempt, retryOptions) {
|
|
|
501
499
|
function isObjectLike(value) {
|
|
502
500
|
return value && typeof value === "object" && value.constructor?.name === "Object" || Array.isArray(value) || typeof value?.toJSON === "function";
|
|
503
501
|
}
|
|
502
|
+
function serializeQueryParams(params) {
|
|
503
|
+
const searchParams = new URLSearchParams();
|
|
504
|
+
for (const [key, value] of Object.entries(params)) {
|
|
505
|
+
if (Array.isArray(value)) {
|
|
506
|
+
for (const item of value) {
|
|
507
|
+
if (item !== void 0 && item !== null) {
|
|
508
|
+
searchParams.append(key, String(item));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
} else if (value !== void 0 && value !== null) {
|
|
512
|
+
searchParams.append(key, String(value));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return searchParams.toString();
|
|
516
|
+
}
|
|
504
517
|
function serializeRequestBody(body) {
|
|
505
518
|
if (typeof body === "string" || body instanceof FormData || body instanceof URLSearchParams || body instanceof ArrayBuffer || body instanceof Blob || body instanceof ReadableStream) {
|
|
506
519
|
return { body };
|
package/dist/index.es.js.map
CHANGED
|
@@ -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: (\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 : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes,\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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"}
|
|
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 : undefined\n\n const stream = createStreamingStream(\n reader,\n (chunk, totalBytes, transferredBytes) => {\n onUploadStreaming({\n chunk,\n totalBytes,\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 : serializeQueryParams(requestContext.params)\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\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\nfunction serializeQueryParams(params: RequestParamsType): string {\n const searchParams = new URLSearchParams()\n\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item !== undefined && item !== null) {\n searchParams.append(key, String(item))\n }\n }\n } else if (value !== undefined && value !== null) {\n searchParams.append(key, String(value))\n }\n }\n\n return searchParams.toString()\n}\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.
|
|
3
|
+
"version": "0.1.11",
|
|
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",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"sideEffects": false,
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "tsc && vite build",
|
|
20
|
+
"build": "tsc && vite build && node scripts/copy-assets.js",
|
|
21
21
|
"dev": "vite build --watch",
|
|
22
22
|
"test": "vitest --run",
|
|
23
23
|
"test:watch": "vitest",
|
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
"tsc": "tsc --noEmit",
|
|
26
26
|
"lint": "prettier --check .",
|
|
27
27
|
"lint:fix": "prettier --write .",
|
|
28
|
-
"
|
|
29
|
-
"bundle:size": "node ../../scripts/bundle-size.js",
|
|
30
|
-
"bundle": "LIB_BUILD=true vite build && yarn bundle:size",
|
|
28
|
+
"copy-assets": "node scripts/copy-assets.js",
|
|
31
29
|
"clean": "rm -rf dist coverage"
|
|
32
30
|
},
|
|
33
31
|
"keywords": [
|
|
@@ -43,27 +41,27 @@
|
|
|
43
41
|
"valibot",
|
|
44
42
|
"arktype"
|
|
45
43
|
],
|
|
46
|
-
"author": "
|
|
44
|
+
"author": "kioviensis",
|
|
47
45
|
"license": "MIT",
|
|
48
46
|
"repository": {
|
|
49
47
|
"type": "git",
|
|
50
|
-
"url": "https://github.com/
|
|
48
|
+
"url": "git+https://github.com/kioviensis/1000fetches.git"
|
|
51
49
|
},
|
|
52
50
|
"bugs": {
|
|
53
|
-
"url": "https://github.com/
|
|
51
|
+
"url": "https://github.com/kioviensis/1000fetches/issues"
|
|
54
52
|
},
|
|
55
|
-
"homepage": "https://github.com/
|
|
53
|
+
"homepage": "https://github.com/kioviensis/1000fetches#readme",
|
|
56
54
|
"devDependencies": {
|
|
57
55
|
"@types/node": "22.18.9",
|
|
58
56
|
"@vitest/coverage-v8": "3.2.4",
|
|
59
|
-
"arktype": "2.1.
|
|
57
|
+
"arktype": "2.1.23",
|
|
60
58
|
"expect-type": "1.2.2",
|
|
61
59
|
"msw": "2.11.5",
|
|
62
60
|
"rollup-plugin-visualizer": "6.0.4",
|
|
63
61
|
"terser": "5.44.0",
|
|
64
62
|
"typescript": "5.9.3",
|
|
65
63
|
"valibot": "1.1.0",
|
|
66
|
-
"vite": "7.1.
|
|
64
|
+
"vite": "7.1.10",
|
|
67
65
|
"vite-plugin-dts": "4.5.4",
|
|
68
66
|
"vitest": "3.2.4",
|
|
69
67
|
"zod": "4.1.12"
|