@indra211/httpease 1.0.0

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/LICENSE ADDED
@@ -0,0 +1,40 @@
1
+ Copyright (c) 2026 INDRA211. All rights reserved.
2
+
3
+ PROPRIETARY SOFTWARE LICENSE
4
+
5
+ This software and associated documentation files (the "Software") are the
6
+ exclusive intellectual property of INDRA211 ("the Author").
7
+
8
+ PERMITTED USES
9
+ --------------
10
+ You are permitted to:
11
+ - Install and use the Software in your own projects (personal or commercial).
12
+ - Import or require the Software as a dependency in your applications.
13
+
14
+ RESTRICTIONS
15
+ ------------
16
+ You are NOT permitted to:
17
+ - Copy, modify, merge, adapt, or create derivative works of the Software.
18
+ - Redistribute, sublicense, sell, or transfer the Software or any portion
19
+ of it to any third party.
20
+ - Submit pull requests, patches, or any form of contribution to this project.
21
+ All updates, improvements, and maintenance are exclusively reserved for
22
+ the Author.
23
+ - Remove or alter this license notice from any copy of the Software.
24
+
25
+ NO CONTRIBUTIONS
26
+ ----------------
27
+ This project does not accept external contributions of any kind. The Author
28
+ is the sole maintainer and retains full control over all changes and releases.
29
+ If you discover a bug or have a feature request, you may open an issue for
30
+ the Author's consideration, but no code contributions will be accepted or
31
+ merged.
32
+
33
+ DISCLAIMER
34
+ ----------
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN
39
+ ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN
40
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,425 @@
1
+ # 🚀 HTTP Ease
2
+
3
+ A lightweight, powerful HTTP client for JavaScript & TypeScript — Built on native fetch with automatic retry, interceptors, progress tracking, and more.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/http-ease.svg)](https://www.npmjs.com/package/http-ease)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## âœĻ Why HTTP Ease?
9
+
10
+ HTTP Ease is a modern HTTP client that combines the simplicity of native `fetch` with the power of Axios, **without any dependencies**.
11
+
12
+ ### Key Features
13
+
14
+ - ðŸŠķ **Lightweight** - Zero dependencies, ~5KB gzipped
15
+ - 🔄 **Built-in Retry** - Automatic retry with exponential backoff (unlike Axios!)
16
+ - ðŸŽŊ **Interceptors** - Request and response interceptors like Axios
17
+ - ⚡ **Modern** - Built on native Fetch API
18
+ - ⏱ïļ **Timeout Support** - Automatic request cancellation
19
+ - ðŸ“Ķ **Universal** - Works in Node.js 18+ and all modern browsers
20
+ - ðŸŽĻ **TypeScript Ready** - Full type definitions included, zero extra setup
21
+ - 📊 **Progress Tracking** - Upload & download progress via native streams
22
+ - 🔧 **Customizable** - Transform requests/responses, custom validators
23
+
24
+ ## ðŸ“Ķ Installation
25
+
26
+ ```bash
27
+ npm install httpease
28
+ ```
29
+
30
+ ## ðŸŽŊ Quick Start
31
+
32
+ ### JavaScript
33
+ ```javascript
34
+ const httpEase = require('httpease');
35
+
36
+ // Simple GET request
37
+ const response = await httpEase.get('https://api.example.com/users');
38
+ console.log(response.data);
39
+
40
+ // POST request
41
+ const newUser = await httpEase.post('https://api.example.com/users', {
42
+ name: 'John Doe',
43
+ email: 'john@example.com'
44
+ });
45
+ ```
46
+
47
+ ### TypeScript
48
+ ```typescript
49
+ import httpEase, { create, HttpEaseResponse } from 'httpease';
50
+
51
+ interface User {
52
+ id: number;
53
+ name: string;
54
+ email: string;
55
+ }
56
+
57
+ // Fully typed response
58
+ const response = await httpEase.get<User[]>('https://api.example.com/users');
59
+ const users: User[] = response.data; // ✅ type-safe
60
+
61
+ // Create a typed instance
62
+ const api = create({ baseURL: 'https://api.example.com' });
63
+
64
+ const user = await api.get<User>('/users/1');
65
+ console.log(user.data.name); // ✅ IntelliSense works
66
+ ```
67
+
68
+ ## 📖 Documentation
69
+
70
+ ### Creating an Instance
71
+
72
+ ```typescript
73
+ import { create } from 'httpease';
74
+
75
+ const api = create({
76
+ baseURL: 'https://api.example.com',
77
+ timeout: 10000,
78
+ headers: {
79
+ 'Authorization': 'Bearer YOUR_TOKEN',
80
+ 'Content-Type': 'application/json'
81
+ },
82
+ retries: 3,
83
+ retryDelay: 1000
84
+ });
85
+ ```
86
+
87
+ ### Making Requests
88
+
89
+ ```typescript
90
+ // GET
91
+ const users = await api.get('/users');
92
+ const user = await api.get('/users/123');
93
+
94
+ // GET with query parameters
95
+ const filtered = await api.get('/users', {
96
+ params: {
97
+ role: 'admin',
98
+ active: true
99
+ }
100
+ });
101
+
102
+ // POST
103
+ const created = await api.post('/users', {
104
+ name: 'Jane Doe',
105
+ email: 'jane@example.com'
106
+ });
107
+
108
+ // PUT
109
+ const updated = await api.put('/users/123', { name: 'Jane Smith' });
110
+
111
+ // PATCH
112
+ const patched = await api.patch('/users/123', { email: 'jane.smith@example.com' });
113
+
114
+ // DELETE
115
+ await api.delete('/users/123');
116
+
117
+ // HEAD
118
+ const headers = await api.head('/users/123');
119
+
120
+ // OPTIONS
121
+ const options = await api.options('/users');
122
+ ```
123
+
124
+ ### Response Object
125
+
126
+ ```typescript
127
+ {
128
+ data: {}, // Parsed response data (auto-JSON)
129
+ status: 200, // HTTP status code
130
+ statusText: 'OK', // HTTP status text
131
+ headers: {}, // Response headers (plain object)
132
+ config: {}, // Request configuration used
133
+ request: {}, // { url, method }
134
+ duration: 234 // Round-trip time in ms
135
+ }
136
+ ```
137
+
138
+ ### TypeScript — Generic Responses
139
+
140
+ No type assertions needed. Pass the expected type as a generic:
141
+
142
+ ```typescript
143
+ interface Product {
144
+ id: number;
145
+ name: string;
146
+ price: number;
147
+ }
148
+
149
+ // api.get<T> → Promise<HttpEaseResponse<T>>
150
+ const { data } = await api.get<Product[]>('/products');
151
+ // ^ Product[] — fully typed, no casting
152
+
153
+ const { data: product } = await api.post<Product>('/products', {
154
+ name: 'Widget',
155
+ price: 9.99
156
+ });
157
+ ```
158
+
159
+ ### 📊 Progress Tracking
160
+
161
+ Progress tracking works with **zero dependencies** using native `ReadableStream` / `TransformStream` (Node.js 18+, all modern browsers).
162
+
163
+ **Download Progress:**
164
+
165
+ ```typescript
166
+ const response = await api.get('/files/large-dataset.json', {
167
+ onDownloadProgress: ({ loaded, total, percentage }) => {
168
+ if (total > 0) {
169
+ process.stdout.write(`\rDownloading... ${percentage.toFixed(1)}%`);
170
+ } else {
171
+ console.log(`Downloaded ${loaded} bytes`);
172
+ }
173
+ }
174
+ });
175
+ console.log('\nDone!', response.data);
176
+ ```
177
+
178
+ **Upload Progress:**
179
+
180
+ ```typescript
181
+ const payload = JSON.stringify({ items: largeArray });
182
+
183
+ const response = await api.post('/data/import', payload, {
184
+ onUploadProgress: ({ loaded, total, percentage }) => {
185
+ console.log(`Uploading: ${percentage.toFixed(1)}% (${loaded}/${total} bytes)`);
186
+ }
187
+ });
188
+ ```
189
+
190
+ **With FormData (browser):**
191
+
192
+ ```typescript
193
+ const form = new FormData();
194
+ form.append('file', fileInput.files[0]);
195
+
196
+ await api.post('/upload', form, {
197
+ onUploadProgress: ({ loaded, total, percentage }) => {
198
+ progressBar.style.width = `${percentage}%`;
199
+ }
200
+ });
201
+ ```
202
+
203
+ **Progress Event Object:**
204
+
205
+ ```typescript
206
+ interface ProgressEvent {
207
+ loaded: number; // bytes transferred so far
208
+ total: number; // total bytes (0 if unknown — no Content-Length)
209
+ percentage: number; // 0–100, or 0 when total is unknown
210
+ }
211
+ ```
212
+
213
+ > **Note:** Upload progress requires `TransformStream` (Node.js 18+, Chrome 67+, Firefox 102+, Safari 14.1+). The library falls back silently to a non-streaming body in older environments.
214
+
215
+ ### Interceptors
216
+
217
+ **Request Interceptor:**
218
+
219
+ ```typescript
220
+ api.interceptors.request.use(
221
+ (config) => {
222
+ // Modify request before sending
223
+ config.headers['X-Custom-Header'] = 'value';
224
+ console.log('Sending request to:', config.url);
225
+ return config;
226
+ },
227
+ (error) => {
228
+ return Promise.reject(error);
229
+ }
230
+ );
231
+ ```
232
+
233
+ **Response Interceptor:**
234
+
235
+ ```typescript
236
+ api.interceptors.response.use(
237
+ (response) => {
238
+ console.log('Received:', response.status);
239
+ return response;
240
+ },
241
+ (error) => {
242
+ if (error.response?.status === 401) {
243
+ // Redirect to login
244
+ }
245
+ return Promise.reject(error);
246
+ }
247
+ );
248
+ ```
249
+
250
+ **Remove an interceptor:**
251
+
252
+ ```typescript
253
+ const id = api.interceptors.request.use(myHandler);
254
+ api.interceptors.request.eject(id); // remove one
255
+ api.interceptors.request.clear(); // remove all
256
+ ```
257
+
258
+ ### Automatic Retry
259
+
260
+ **Basic Retry:**
261
+
262
+ ```typescript
263
+ const api = create({
264
+ baseURL: 'https://api.example.com',
265
+ retries: 3, // Retry up to 3 times
266
+ retryDelay: 1000, // Start with 1 second delay
267
+ onRetry: (attempt, delay, error) => {
268
+ console.log(`Retry ${attempt} after ${delay}ms`);
269
+ }
270
+ });
271
+ ```
272
+
273
+ **Custom Retry Logic:**
274
+
275
+ ```typescript
276
+ const api = create({
277
+ retries: 5,
278
+ retryDelay: (attempt) => {
279
+ // Custom backoff: 1s, 2s, 4s, 8s, 16s
280
+ return Math.pow(2, attempt - 1) * 1000;
281
+ },
282
+ retryCondition: (error, attempt) => {
283
+ // Only retry on network errors and 503
284
+ if (!error.response) return true;
285
+ return error.response.status === 503;
286
+ }
287
+ });
288
+ ```
289
+
290
+ **Per-Request Retry:**
291
+
292
+ ```typescript
293
+ // Override retry config for a specific request
294
+ await api.get('/critical-endpoint', {
295
+ retries: 5,
296
+ retryDelay: 2000
297
+ });
298
+ ```
299
+
300
+ ### Error Handling
301
+
302
+ ```typescript
303
+ import { HttpEaseError } from 'httpease';
304
+
305
+ try {
306
+ const response = await api.get('/users/999');
307
+ } catch (error) {
308
+ if (error.isHttpError) {
309
+ if (error.response) {
310
+ // Server responded with error status
311
+ console.error('Status:', error.response.status);
312
+ console.error('Data:', error.response.data);
313
+ } else if (error.code === 'ETIMEDOUT') {
314
+ console.error('Request timed out');
315
+ } else {
316
+ console.error('Network error:', error.message);
317
+ }
318
+ }
319
+ }
320
+ ```
321
+
322
+ ### Configuration Options
323
+
324
+ ```typescript
325
+ {
326
+ // Base URL for all requests
327
+ baseURL: 'https://api.example.com',
328
+
329
+ // Request timeout in milliseconds (default: 30000)
330
+ timeout: 30000,
331
+
332
+ // Custom headers
333
+ headers: { 'Content-Type': 'application/json' },
334
+
335
+ // Number of retry attempts (default: 0)
336
+ retries: 0,
337
+
338
+ // Retry delay — ms number or function
339
+ retryDelay: 1000,
340
+ // retryDelay: (attempt) => Math.pow(2, attempt - 1) * 1000,
341
+
342
+ // Custom retry condition
343
+ retryCondition: (error, attempt) => boolean,
344
+
345
+ // Callback on retry
346
+ onRetry: (attempt, delay, error) => void,
347
+
348
+ // Query parameters
349
+ params: {},
350
+
351
+ // Request data
352
+ data: {},
353
+
354
+ // Validate status code
355
+ validateStatus: (status) => status >= 200 && status < 300,
356
+
357
+ // Include credentials (CORS)
358
+ withCredentials: false,
359
+
360
+ // Transform request data before sending
361
+ transformRequest: [(data, headers) => data],
362
+
363
+ // Transform response data after receiving
364
+ transformResponse: [(data) => data],
365
+
366
+ // Upload progress callback
367
+ onUploadProgress: ({ loaded, total, percentage }) => void,
368
+
369
+ // Download progress callback
370
+ onDownloadProgress: ({ loaded, total, percentage }) => void,
371
+ }
372
+ ```
373
+
374
+ ## 🆚 Comparison with Axios
375
+
376
+ | Feature | HTTP Ease | Axios |
377
+ | ----------------------------| --------- | -------------------- |
378
+ | **Size** | ~5KB | ~13KB |
379
+ | **Dependencies** | 0 | Many |
380
+ | **Built-in Retry** | ✅ Yes | ❌ No (needs plugin) |
381
+ | **Interceptors** | ✅ Yes | ✅ Yes |
382
+ | **Timeout** | ✅ Yes | ✅ Yes |
383
+ | **Auto JSON** | ✅ Yes | ✅ Yes |
384
+ | **Query Params** | ✅ Yes | ✅ Yes |
385
+ | **Progress Tracking** | ✅ Yes | ✅ Yes |
386
+ | **Cancel Requests** | ✅ Yes | ✅ Yes |
387
+ | **TypeScript** | ✅ Yes | ✅ Yes |
388
+
389
+ ## ðŸŽŊ Use Cases
390
+
391
+ Perfect for:
392
+
393
+ - ✅ Building typed API clients in TypeScript
394
+ - ✅ Making HTTP requests in React/Vue/Angular apps
395
+ - ✅ Node.js backend services
396
+ - ✅ File upload/download with progress UI
397
+ - ✅ Projects where bundle size matters
398
+ - ✅ Apps needing automatic retry logic
399
+
400
+ ## 📝 Examples
401
+
402
+ Check out the `/examples` directory for:
403
+
404
+ - `basic.js` - Basic usage examples
405
+ - `interceptors.js` - Request/response interceptors
406
+ - `retry.js` - Retry configuration examples
407
+ - `progress.js` - Upload & download progress examples
408
+
409
+ ## ðŸšŦ Contributing
410
+
411
+ This project does **not** accept external contributions. Only the author pushes updates and new releases. If you encounter a bug or have a feature idea, you are welcome to open an issue — but pull requests and code patches will not be reviewed or merged.
412
+
413
+ ## 📄 License
414
+
415
+ Proprietary ÂĐ 2026 **INDRA211**. All rights reserved.
416
+
417
+ This software is **not open source**. You may install and use it in your projects, but you may not copy, modify, redistribute, or contribute to it. See the [LICENSE](./LICENSE) file for full terms.
418
+
419
+ ## 🙏 Acknowledgments
420
+
421
+ Inspired by [Axios](https://github.com/axios/axios) but built for the modern web with native fetch and zero dependencies.
422
+
423
+ ---
424
+
425
+ **Made with âĪïļ by INDRA211**
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@indra211/httpease",
3
+ "version": "1.0.0",
4
+ "description": "Lightweight HTTP client built on native fetch — zero dependencies, TypeScript support, retry, interceptors & progress tracking.",
5
+ "main": "src/index.js",
6
+ "types": "src/types/index.d.ts",
7
+ "files": [
8
+ "src/",
9
+ "LICENSE",
10
+ "README.md"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18.0.0"
14
+ },
15
+ "scripts": {
16
+ "test": "node test/test.js"
17
+ },
18
+ "keywords": [
19
+ "http",
20
+ "fetch",
21
+ "client",
22
+ "typescript",
23
+ "retry",
24
+ "interceptors",
25
+ "progress",
26
+ "http-client",
27
+ "zero-dependency",
28
+ "upload-progress",
29
+ "download-progress"
30
+ ],
31
+ "author": "INDRA211",
32
+ "license": "UNLICENSED",
33
+ "private": false,
34
+ "type": "commonjs"
35
+ }