1000fetches 0.1.9 → 0.1.10

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 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
+ [![npm version](https://img.shields.io/npm/v/1000fetches?style=flat-square)](https://www.npmjs.com/package/1000fetches)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "1000fetches",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
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
- "bundle:analyze": "LIB_BUILD=true vite build --mode analyze",
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": "Your Name",
44
+ "author": "kioviensis",
47
45
  "license": "MIT",
48
46
  "repository": {
49
47
  "type": "git",
50
- "url": "https://github.com/your-username/1000fetches.git"
48
+ "url": "git+https://github.com/kioviensis/1000fetches.git"
51
49
  },
52
50
  "bugs": {
53
- "url": "https://github.com/your-username/1000fetches/issues"
51
+ "url": "https://github.com/kioviensis/1000fetches/issues"
54
52
  },
55
- "homepage": "https://github.com/your-username/1000fetches#readme",
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.22",
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.9",
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"