@fgrzl/fetch 1.1.0-alpha.3 → 1.1.0-alpha.8

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.
Files changed (231) hide show
  1. package/README.md +15 -12
  2. package/dist/cjs/client/fetch-client.d.ts +189 -0
  3. package/dist/cjs/client/fetch-client.d.ts.map +1 -0
  4. package/dist/cjs/client/fetch-client.js +339 -0
  5. package/dist/cjs/client/fetch-client.js.map +1 -0
  6. package/dist/cjs/client/index.d.ts +11 -0
  7. package/dist/cjs/client/index.d.ts.map +1 -0
  8. package/dist/cjs/client/index.js +14 -0
  9. package/dist/cjs/client/index.js.map +1 -0
  10. package/dist/cjs/client/types.d.ts +63 -0
  11. package/dist/cjs/client/types.d.ts.map +1 -0
  12. package/dist/cjs/client/types.js +9 -0
  13. package/dist/cjs/client/types.js.map +1 -0
  14. package/dist/{errors.d.ts → cjs/errors/index.d.ts} +20 -3
  15. package/dist/cjs/errors/index.d.ts.map +1 -0
  16. package/dist/{errors.js → cjs/errors/index.js} +23 -3
  17. package/dist/cjs/errors/index.js.map +1 -0
  18. package/dist/cjs/index.d.ts +65 -0
  19. package/dist/cjs/index.d.ts.map +1 -0
  20. package/dist/cjs/index.js +118 -0
  21. package/dist/cjs/index.js.map +1 -0
  22. package/dist/cjs/middleware/authentication/authentication.d.ts +31 -0
  23. package/dist/cjs/middleware/authentication/authentication.d.ts.map +1 -0
  24. package/dist/cjs/middleware/authentication/authentication.js +93 -0
  25. package/dist/cjs/middleware/authentication/authentication.js.map +1 -0
  26. package/dist/cjs/middleware/authentication/index.d.ts +37 -0
  27. package/dist/cjs/middleware/authentication/index.d.ts.map +1 -0
  28. package/dist/cjs/middleware/authentication/index.js +42 -0
  29. package/dist/cjs/middleware/authentication/index.js.map +1 -0
  30. package/dist/cjs/middleware/authentication/types.d.ts +73 -0
  31. package/dist/cjs/middleware/authentication/types.d.ts.map +1 -0
  32. package/dist/cjs/middleware/authentication/types.js +6 -0
  33. package/dist/cjs/middleware/authentication/types.js.map +1 -0
  34. package/dist/cjs/middleware/authorization/authorization.d.ts +30 -0
  35. package/dist/cjs/middleware/authorization/authorization.d.ts.map +1 -0
  36. package/dist/cjs/middleware/authorization/authorization.js +82 -0
  37. package/dist/cjs/middleware/authorization/authorization.js.map +1 -0
  38. package/dist/cjs/middleware/authorization/index.d.ts +36 -0
  39. package/dist/cjs/middleware/authorization/index.d.ts.map +1 -0
  40. package/dist/cjs/middleware/authorization/index.js +41 -0
  41. package/dist/cjs/middleware/authorization/index.js.map +1 -0
  42. package/dist/cjs/middleware/authorization/types.d.ts +67 -0
  43. package/dist/cjs/middleware/authorization/types.d.ts.map +1 -0
  44. package/dist/cjs/middleware/authorization/types.js +6 -0
  45. package/dist/cjs/middleware/authorization/types.js.map +1 -0
  46. package/dist/cjs/middleware/cache/cache.d.ts +41 -0
  47. package/dist/cjs/middleware/cache/cache.d.ts.map +1 -0
  48. package/dist/cjs/middleware/cache/cache.js +191 -0
  49. package/dist/cjs/middleware/cache/cache.js.map +1 -0
  50. package/dist/cjs/middleware/cache/index.d.ts +44 -0
  51. package/dist/cjs/middleware/cache/index.d.ts.map +1 -0
  52. package/dist/cjs/middleware/cache/index.js +50 -0
  53. package/dist/cjs/middleware/cache/index.js.map +1 -0
  54. package/dist/cjs/middleware/cache/types.d.ts +89 -0
  55. package/dist/cjs/middleware/cache/types.d.ts.map +1 -0
  56. package/dist/cjs/middleware/cache/types.js +6 -0
  57. package/dist/cjs/middleware/cache/types.js.map +1 -0
  58. package/dist/cjs/middleware/csrf/csrf.d.ts +34 -0
  59. package/dist/cjs/middleware/csrf/csrf.d.ts.map +1 -0
  60. package/dist/cjs/middleware/csrf/csrf.js +94 -0
  61. package/dist/cjs/middleware/csrf/csrf.js.map +1 -0
  62. package/dist/cjs/middleware/csrf/index.d.ts +57 -0
  63. package/dist/cjs/middleware/csrf/index.d.ts.map +1 -0
  64. package/dist/cjs/middleware/csrf/index.js +62 -0
  65. package/dist/cjs/middleware/csrf/index.js.map +1 -0
  66. package/dist/cjs/middleware/csrf/types.d.ts +57 -0
  67. package/dist/cjs/middleware/csrf/types.d.ts.map +1 -0
  68. package/dist/cjs/middleware/csrf/types.js +6 -0
  69. package/dist/cjs/middleware/csrf/types.js.map +1 -0
  70. package/dist/cjs/middleware/index.d.ts +115 -0
  71. package/dist/cjs/middleware/index.d.ts.map +1 -0
  72. package/dist/cjs/middleware/index.js +153 -0
  73. package/dist/cjs/middleware/index.js.map +1 -0
  74. package/dist/cjs/middleware/logging/index.d.ts +42 -0
  75. package/dist/cjs/middleware/logging/index.d.ts.map +1 -0
  76. package/dist/cjs/middleware/logging/index.js +47 -0
  77. package/dist/cjs/middleware/logging/index.js.map +1 -0
  78. package/dist/cjs/middleware/logging/logging.d.ts +29 -0
  79. package/dist/cjs/middleware/logging/logging.d.ts.map +1 -0
  80. package/dist/cjs/middleware/logging/logging.js +171 -0
  81. package/dist/cjs/middleware/logging/logging.js.map +1 -0
  82. package/dist/cjs/middleware/logging/types.d.ts +90 -0
  83. package/dist/cjs/middleware/logging/types.d.ts.map +1 -0
  84. package/dist/cjs/middleware/logging/types.js +6 -0
  85. package/dist/cjs/middleware/logging/types.js.map +1 -0
  86. package/dist/cjs/middleware/rate-limit/index.d.ts +16 -0
  87. package/dist/cjs/middleware/rate-limit/index.d.ts.map +1 -0
  88. package/dist/cjs/middleware/rate-limit/index.js +21 -0
  89. package/dist/cjs/middleware/rate-limit/index.js.map +1 -0
  90. package/dist/cjs/middleware/rate-limit/rate-limit.d.ts +14 -0
  91. package/dist/cjs/middleware/rate-limit/rate-limit.d.ts.map +1 -0
  92. package/dist/cjs/middleware/rate-limit/rate-limit.js +87 -0
  93. package/dist/cjs/middleware/rate-limit/rate-limit.js.map +1 -0
  94. package/dist/cjs/middleware/rate-limit/types.d.ts +97 -0
  95. package/dist/cjs/middleware/rate-limit/types.d.ts.map +1 -0
  96. package/dist/cjs/middleware/rate-limit/types.js +6 -0
  97. package/dist/cjs/middleware/rate-limit/types.js.map +1 -0
  98. package/dist/cjs/middleware/retry/index.d.ts +6 -0
  99. package/dist/cjs/middleware/retry/index.d.ts.map +1 -0
  100. package/dist/cjs/middleware/retry/index.js +11 -0
  101. package/dist/cjs/middleware/retry/index.js.map +1 -0
  102. package/dist/cjs/middleware/retry/retry.d.ts +39 -0
  103. package/dist/cjs/middleware/retry/retry.d.ts.map +1 -0
  104. package/dist/cjs/middleware/retry/retry.js +144 -0
  105. package/dist/cjs/middleware/retry/retry.js.map +1 -0
  106. package/dist/cjs/middleware/retry/types.d.ts +61 -0
  107. package/dist/cjs/middleware/retry/types.d.ts.map +1 -0
  108. package/dist/cjs/middleware/retry/types.js +6 -0
  109. package/dist/cjs/middleware/retry/types.js.map +1 -0
  110. package/dist/client/fetch-client.d.ts +189 -0
  111. package/dist/client/fetch-client.d.ts.map +1 -0
  112. package/dist/client/fetch-client.js +335 -0
  113. package/dist/client/fetch-client.js.map +1 -0
  114. package/dist/client/index.d.ts +11 -0
  115. package/dist/client/index.d.ts.map +1 -0
  116. package/dist/client/index.js +10 -0
  117. package/dist/client/index.js.map +1 -0
  118. package/dist/client/types.d.ts +63 -0
  119. package/dist/client/types.d.ts.map +1 -0
  120. package/dist/client/types.js +8 -0
  121. package/dist/client/types.js.map +1 -0
  122. package/dist/errors/index.d.ts +64 -0
  123. package/dist/errors/index.d.ts.map +1 -0
  124. package/dist/errors/index.js +73 -0
  125. package/dist/errors/index.js.map +1 -0
  126. package/dist/index.d.ts +49 -20
  127. package/dist/index.d.ts.map +1 -0
  128. package/dist/index.js +86 -42
  129. package/dist/index.js.map +1 -1
  130. package/dist/middleware/authentication/authentication.d.ts +31 -0
  131. package/dist/middleware/authentication/authentication.d.ts.map +1 -0
  132. package/dist/middleware/authentication/authentication.js +90 -0
  133. package/dist/middleware/authentication/authentication.js.map +1 -0
  134. package/dist/middleware/authentication/index.d.ts +37 -0
  135. package/dist/middleware/authentication/index.d.ts.map +1 -0
  136. package/dist/middleware/authentication/index.js +37 -0
  137. package/dist/middleware/authentication/index.js.map +1 -0
  138. package/dist/middleware/authentication/types.d.ts +73 -0
  139. package/dist/middleware/authentication/types.d.ts.map +1 -0
  140. package/dist/middleware/authentication/types.js +5 -0
  141. package/dist/middleware/authentication/types.js.map +1 -0
  142. package/dist/middleware/authorization/authorization.d.ts +30 -0
  143. package/dist/middleware/authorization/authorization.d.ts.map +1 -0
  144. package/dist/middleware/authorization/authorization.js +79 -0
  145. package/dist/middleware/authorization/authorization.js.map +1 -0
  146. package/dist/middleware/authorization/index.d.ts +36 -0
  147. package/dist/middleware/authorization/index.d.ts.map +1 -0
  148. package/dist/middleware/authorization/index.js +36 -0
  149. package/dist/middleware/authorization/index.js.map +1 -0
  150. package/dist/middleware/authorization/types.d.ts +67 -0
  151. package/dist/middleware/authorization/types.d.ts.map +1 -0
  152. package/dist/middleware/authorization/types.js +5 -0
  153. package/dist/middleware/authorization/types.js.map +1 -0
  154. package/dist/middleware/cache/cache.d.ts +41 -0
  155. package/dist/middleware/cache/cache.d.ts.map +1 -0
  156. package/dist/middleware/cache/cache.js +186 -0
  157. package/dist/middleware/cache/cache.js.map +1 -0
  158. package/dist/middleware/cache/index.d.ts +44 -0
  159. package/dist/middleware/cache/index.d.ts.map +1 -0
  160. package/dist/middleware/cache/index.js +44 -0
  161. package/dist/middleware/cache/index.js.map +1 -0
  162. package/dist/middleware/cache/types.d.ts +89 -0
  163. package/dist/middleware/cache/types.d.ts.map +1 -0
  164. package/dist/middleware/cache/types.js +5 -0
  165. package/dist/middleware/cache/types.js.map +1 -0
  166. package/dist/middleware/csrf/csrf.d.ts +34 -0
  167. package/dist/middleware/csrf/csrf.d.ts.map +1 -0
  168. package/dist/middleware/csrf/csrf.js +91 -0
  169. package/dist/middleware/csrf/csrf.js.map +1 -0
  170. package/dist/middleware/csrf/index.d.ts +57 -0
  171. package/dist/middleware/csrf/index.d.ts.map +1 -0
  172. package/dist/middleware/csrf/index.js +57 -0
  173. package/dist/middleware/csrf/index.js.map +1 -0
  174. package/dist/middleware/csrf/types.d.ts +57 -0
  175. package/dist/middleware/csrf/types.d.ts.map +1 -0
  176. package/dist/middleware/csrf/types.js +5 -0
  177. package/dist/middleware/csrf/types.js.map +1 -0
  178. package/dist/middleware/index.d.ts +115 -0
  179. package/dist/middleware/index.d.ts.map +1 -0
  180. package/dist/middleware/index.js +134 -0
  181. package/dist/middleware/index.js.map +1 -0
  182. package/dist/middleware/logging/index.d.ts +42 -0
  183. package/dist/middleware/logging/index.d.ts.map +1 -0
  184. package/dist/middleware/logging/index.js +42 -0
  185. package/dist/middleware/logging/index.js.map +1 -0
  186. package/dist/middleware/logging/logging.d.ts +29 -0
  187. package/dist/middleware/logging/logging.d.ts.map +1 -0
  188. package/dist/middleware/logging/logging.js +168 -0
  189. package/dist/middleware/logging/logging.js.map +1 -0
  190. package/dist/middleware/logging/types.d.ts +90 -0
  191. package/dist/middleware/logging/types.d.ts.map +1 -0
  192. package/dist/middleware/logging/types.js +5 -0
  193. package/dist/middleware/logging/types.js.map +1 -0
  194. package/dist/middleware/rate-limit/index.d.ts +16 -0
  195. package/dist/middleware/rate-limit/index.d.ts.map +1 -0
  196. package/dist/middleware/rate-limit/index.js +16 -0
  197. package/dist/middleware/rate-limit/index.js.map +1 -0
  198. package/dist/middleware/rate-limit/rate-limit.d.ts +14 -0
  199. package/dist/middleware/rate-limit/rate-limit.d.ts.map +1 -0
  200. package/dist/middleware/rate-limit/rate-limit.js +84 -0
  201. package/dist/middleware/rate-limit/rate-limit.js.map +1 -0
  202. package/dist/middleware/rate-limit/types.d.ts +97 -0
  203. package/dist/middleware/rate-limit/types.d.ts.map +1 -0
  204. package/dist/middleware/rate-limit/types.js +5 -0
  205. package/dist/middleware/rate-limit/types.js.map +1 -0
  206. package/dist/middleware/retry/index.d.ts +6 -0
  207. package/dist/middleware/retry/index.d.ts.map +1 -0
  208. package/dist/middleware/retry/index.js +6 -0
  209. package/dist/middleware/retry/index.js.map +1 -0
  210. package/dist/middleware/retry/retry.d.ts +39 -0
  211. package/dist/middleware/retry/retry.d.ts.map +1 -0
  212. package/dist/middleware/retry/retry.js +141 -0
  213. package/dist/middleware/retry/retry.js.map +1 -0
  214. package/dist/middleware/retry/types.d.ts +61 -0
  215. package/dist/middleware/retry/types.d.ts.map +1 -0
  216. package/dist/middleware/retry/types.js +5 -0
  217. package/dist/middleware/retry/types.js.map +1 -0
  218. package/package.json +42 -8
  219. package/dist/client.d.ts +0 -133
  220. package/dist/client.js +0 -166
  221. package/dist/client.js.map +0 -1
  222. package/dist/csrf.d.ts +0 -32
  223. package/dist/csrf.js +0 -53
  224. package/dist/csrf.js.map +0 -1
  225. package/dist/errors.js.map +0 -1
  226. package/dist/test-utils.d.ts +0 -24
  227. package/dist/test-utils.js +0 -52
  228. package/dist/test-utils.js.map +0 -1
  229. package/dist/unauthorized.d.ts +0 -27
  230. package/dist/unauthorized.js +0 -41
  231. package/dist/unauthorized.js.map +0 -1
package/README.md CHANGED
@@ -7,9 +7,11 @@ A lightweight, middleware-friendly fetch client for TypeScript projects.
7
7
 
8
8
  ## ✨ Features
9
9
 
10
+ - **Pit of Success Design**: Simple defaults that just work, customizable when needed
10
11
  - Simple API: `api.get('/api/user')`
11
- - Built-in CSRF token support
12
+ - Built-in CSRF token support (XSRF-TOKEN standard)
12
13
  - Automatic 401 redirect handling
14
+ - Retry middleware with configurable strategies
13
15
  - Custom middleware support (request/response)
14
16
  - TypeScript-first, small and dependency-free
15
17
 
@@ -21,6 +23,8 @@ npm install @fgrzl/fetch
21
23
 
22
24
  ## 🚀 Quick Start
23
25
 
26
+ **Level 1: Just works with defaults**
27
+
24
28
  ```ts
25
29
  import api from "@fgrzl/fetch";
26
30
 
@@ -32,26 +36,25 @@ if (response.ok) {
32
36
  }
33
37
  ```
34
38
 
35
- Or create a custom instance:
39
+ **Level 2: Custom configuration when needed**
36
40
 
37
41
  ```ts
38
- import { FetchClient, useCSRF, useUnauthorized } from "@fgrzl/fetch";
42
+ import { FetchClient, useCSRF, useAuthorization, useRetry } from "@fgrzl/fetch";
39
43
 
40
44
  const client = new FetchClient({
41
45
  credentials: "same-origin",
42
46
  });
43
47
 
44
- useCSRF(client, {
45
- cookieName: "csrf_token",
46
- headerName: "X-CSRF-Token",
47
- });
48
-
49
- useUnauthorized(client, {
50
- loginPath: "/login",
51
- });
48
+ // Smart defaults - just works
49
+ useCSRF(client);
50
+ useAuthorization(client);
51
+ useRetry(client);
52
52
 
53
53
  // All requests now return FetchResponse<T>
54
- interface User { id: number; name: string; }
54
+ interface User {
55
+ id: number;
56
+ name: string;
57
+ }
55
58
  const userResponse = await client.get<User>("/api/user");
56
59
  if (userResponse.ok) {
57
60
  console.log(userResponse.data.name); // Typed access to data
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @fileoverview Enhanced fetch client with intercept middleware architecture.
3
+ */
4
+ import type { FetchResponse, FetchClientOptions } from './types';
5
+ /**
6
+ * Intercept middleware type that allows full control over request/response cycle.
7
+ * Middleware can modify requests, handle responses, implement retries, etc.
8
+ */
9
+ export type FetchMiddleware = (request: RequestInit & {
10
+ url?: string;
11
+ }, next: (modifiedRequest?: RequestInit & {
12
+ url?: string;
13
+ }) => Promise<FetchResponse<unknown>>) => Promise<FetchResponse<unknown>>;
14
+ /**
15
+ * Enhanced HTTP client with intercept middleware architecture.
16
+ *
17
+ * Features:
18
+ * - 🎯 Smart defaults (JSON content-type, same-origin credentials)
19
+ * - 🔧 Powerful middleware system for cross-cutting concerns
20
+ * - 🛡️ Consistent error handling (never throws, always returns response)
21
+ * - 📦 TypeScript-first with full type inference
22
+ * - 🚀 Modern async/await API
23
+ *
24
+ * @example Basic usage:
25
+ * ```typescript
26
+ * const client = new FetchClient();
27
+ *
28
+ * // GET request - just works
29
+ * const users = await client.get<User[]>('/api/users');
30
+ * if (users.ok) {
31
+ * console.log(users.data); // Type is User[]
32
+ * }
33
+ *
34
+ * // POST request - JSON by default
35
+ * const result = await client.post('/api/users', { name: 'John' });
36
+ * ```
37
+ *
38
+ * @example With middleware:
39
+ * ```typescript
40
+ * const client = new FetchClient();
41
+ *
42
+ * // Add auth middleware
43
+ * client.use((request, next) => {
44
+ * request.headers = { ...request.headers, Authorization: 'Bearer token' };
45
+ * return next(request);
46
+ * });
47
+ *
48
+ * // Now all requests include auth
49
+ * const data = await client.get('/api/protected');
50
+ * ```
51
+ */
52
+ export declare class FetchClient {
53
+ private middlewares;
54
+ private credentials;
55
+ constructor(config?: FetchClientOptions);
56
+ use(middleware: FetchMiddleware): this;
57
+ request<T = unknown>(url: string, init?: RequestInit): Promise<FetchResponse<T>>;
58
+ private coreFetch;
59
+ private parseResponse;
60
+ private buildUrlWithParams;
61
+ /**
62
+ * HEAD request with query parameter support.
63
+ *
64
+ * HEAD requests are used to retrieve metadata about a resource without downloading
65
+ * the response body. Useful for checking if a resource exists, getting content length,
66
+ * last modified date, etc.
67
+ *
68
+ * @template T - Expected response data type (will be null for HEAD requests)
69
+ * @param url - Request URL
70
+ * @param params - Query parameters to append to URL
71
+ * @returns Promise resolving to typed response (data will always be null)
72
+ *
73
+ * @example Check if resource exists:
74
+ * ```typescript
75
+ * const headResponse = await client.head('/api/large-file.zip');
76
+ * if (headResponse.ok) {
77
+ * const contentLength = headResponse.headers.get('content-length');
78
+ * const lastModified = headResponse.headers.get('last-modified');
79
+ * console.log(`File size: ${contentLength} bytes`);
80
+ * }
81
+ * ```
82
+ *
83
+ * @example Check with query parameters:
84
+ * ```typescript
85
+ * const exists = await client.head('/api/users', { id: 123 });
86
+ * if (exists.status === 404) {
87
+ * console.log('User not found');
88
+ * }
89
+ * ```
90
+ */
91
+ head<T = null>(url: string, params?: Record<string, string | number | boolean | undefined>): Promise<FetchResponse<T>>;
92
+ /**
93
+ * HEAD request that returns useful metadata about a resource.
94
+ *
95
+ * This is a convenience method that extracts common metadata from HEAD responses
96
+ * for easier consumption.
97
+ *
98
+ * @param url - Request URL
99
+ * @param params - Query parameters to append to URL
100
+ * @returns Promise resolving to response with extracted metadata
101
+ *
102
+ * @example Get resource metadata:
103
+ * ```typescript
104
+ * const metadata = await client.headMetadata('/api/large-file.zip');
105
+ * if (metadata.ok) {
106
+ * console.log('File exists:', metadata.exists);
107
+ * console.log('Content type:', metadata.contentType);
108
+ * console.log('Size:', metadata.contentLength, 'bytes');
109
+ * console.log('Last modified:', metadata.lastModified);
110
+ * }
111
+ * ```
112
+ */
113
+ headMetadata(url: string, params?: Record<string, string | number | boolean | undefined>): Promise<FetchResponse<null> & {
114
+ exists: boolean;
115
+ contentType: string | undefined;
116
+ contentLength: number | undefined;
117
+ lastModified: Date | undefined;
118
+ etag: string | undefined;
119
+ cacheControl: string | undefined;
120
+ }>;
121
+ /**
122
+ * GET request with query parameter support.
123
+ *
124
+ * @template T - Expected response data type
125
+ * @param url - Request URL
126
+ * @param params - Query parameters to append to URL
127
+ * @returns Promise resolving to typed response
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * const users = await client.get<User[]>('/api/users');
132
+ * const filteredUsers = await client.get<User[]>('/api/users', { status: 'active', limit: 10 });
133
+ * if (users.ok) console.log(users.data);
134
+ * ```
135
+ */
136
+ get<T>(url: string, params?: Record<string, string | number | boolean | undefined>): Promise<FetchResponse<T>>;
137
+ /**
138
+ * POST request with automatic JSON serialization.
139
+ *
140
+ * @template T - Expected response data type
141
+ * @param url - Request URL
142
+ * @param body - Request body (auto-serialized to JSON)
143
+ * @param headers - Additional headers (Content-Type: application/json is default)
144
+ * @returns Promise resolving to typed response
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const result = await client.post<User>('/api/users', { name: 'John' });
149
+ * ```
150
+ */
151
+ post<T>(url: string, body?: unknown, headers?: Record<string, string>): Promise<FetchResponse<T>>;
152
+ /**
153
+ * PUT request with automatic JSON serialization.
154
+ *
155
+ * @template T - Expected response data type
156
+ * @param url - Request URL
157
+ * @param body - Request body (auto-serialized to JSON)
158
+ * @param headers - Additional headers (Content-Type: application/json is default)
159
+ * @returns Promise resolving to typed response
160
+ */
161
+ put<T>(url: string, body?: unknown, headers?: Record<string, string>): Promise<FetchResponse<T>>;
162
+ /**
163
+ * PATCH request with automatic JSON serialization.
164
+ *
165
+ * @template T - Expected response data type
166
+ * @param url - Request URL
167
+ * @param body - Request body (auto-serialized to JSON)
168
+ * @param headers - Additional headers (Content-Type: application/json is default)
169
+ * @returns Promise resolving to typed response
170
+ */
171
+ patch<T>(url: string, body?: unknown, headers?: Record<string, string>): Promise<FetchResponse<T>>;
172
+ /**
173
+ * DELETE request with query parameter support.
174
+ *
175
+ * @template T - Expected response data type
176
+ * @param url - Request URL
177
+ * @param params - Query parameters to append to URL
178
+ * @returns Promise resolving to typed response
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const result = await client.del('/api/users/123');
183
+ * const bulkResult = await client.del('/api/users', { status: 'inactive', force: true });
184
+ * if (result.ok) console.log('Deleted successfully');
185
+ * ```
186
+ */
187
+ del<T>(url: string, params?: Record<string, string | number | boolean | undefined>): Promise<FetchResponse<T>>;
188
+ }
189
+ //# sourceMappingURL=fetch-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-client.d.ts","sourceRoot":"","sources":["../../../src/client/fetch-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Enhanced fetch client with intercept middleware architecture.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FetchClient = void 0;
7
+ /**
8
+ * Enhanced HTTP client with intercept middleware architecture.
9
+ *
10
+ * Features:
11
+ * - 🎯 Smart defaults (JSON content-type, same-origin credentials)
12
+ * - 🔧 Powerful middleware system for cross-cutting concerns
13
+ * - 🛡️ Consistent error handling (never throws, always returns response)
14
+ * - 📦 TypeScript-first with full type inference
15
+ * - 🚀 Modern async/await API
16
+ *
17
+ * @example Basic usage:
18
+ * ```typescript
19
+ * const client = new FetchClient();
20
+ *
21
+ * // GET request - just works
22
+ * const users = await client.get<User[]>('/api/users');
23
+ * if (users.ok) {
24
+ * console.log(users.data); // Type is User[]
25
+ * }
26
+ *
27
+ * // POST request - JSON by default
28
+ * const result = await client.post('/api/users', { name: 'John' });
29
+ * ```
30
+ *
31
+ * @example With middleware:
32
+ * ```typescript
33
+ * const client = new FetchClient();
34
+ *
35
+ * // Add auth middleware
36
+ * client.use((request, next) => {
37
+ * request.headers = { ...request.headers, Authorization: 'Bearer token' };
38
+ * return next(request);
39
+ * });
40
+ *
41
+ * // Now all requests include auth
42
+ * const data = await client.get('/api/protected');
43
+ * ```
44
+ */
45
+ class FetchClient {
46
+ constructor(config = {}) {
47
+ this.middlewares = [];
48
+ this.credentials = config.credentials ?? 'same-origin';
49
+ }
50
+ use(middleware) {
51
+ this.middlewares.push(middleware);
52
+ return this;
53
+ }
54
+ async request(url, init = {}) {
55
+ // Create the execution chain
56
+ let index = 0;
57
+ const execute = async (request) => {
58
+ // Use provided request or fall back to original
59
+ const currentRequest = request || { ...init, url };
60
+ const currentUrl = currentRequest.url || url;
61
+ if (index >= this.middlewares.length) {
62
+ // Core fetch - end of middleware chain
63
+ const { url: _, ...requestInit } = currentRequest; // Remove url from request init
64
+ return this.coreFetch(requestInit, currentUrl);
65
+ }
66
+ const middleware = this.middlewares[index++];
67
+ if (!middleware) {
68
+ const { url: _, ...requestInit } = currentRequest;
69
+ return this.coreFetch(requestInit, currentUrl);
70
+ }
71
+ return middleware(currentRequest, execute);
72
+ };
73
+ const result = await execute();
74
+ return result;
75
+ }
76
+ async coreFetch(request, url) {
77
+ try {
78
+ const finalInit = {
79
+ credentials: this.credentials,
80
+ ...request,
81
+ };
82
+ // Convert Headers object to plain object for better compatibility
83
+ if (finalInit.headers instanceof Headers) {
84
+ const headersObj = {};
85
+ finalInit.headers.forEach((value, key) => {
86
+ headersObj[key] = value;
87
+ });
88
+ finalInit.headers = headersObj;
89
+ }
90
+ const response = await fetch(url, finalInit);
91
+ const data = await this.parseResponse(response);
92
+ return {
93
+ data: response.ok ? data : null,
94
+ status: response.status,
95
+ statusText: response.statusText,
96
+ headers: response.headers,
97
+ url: response.url,
98
+ ok: response.ok,
99
+ ...(response.ok
100
+ ? {}
101
+ : {
102
+ error: {
103
+ message: response.statusText,
104
+ body: data,
105
+ },
106
+ }),
107
+ };
108
+ }
109
+ catch (error) {
110
+ if (error instanceof TypeError && error.message.includes('fetch')) {
111
+ return {
112
+ data: null,
113
+ status: 0,
114
+ statusText: 'Network Error',
115
+ headers: new Headers(),
116
+ url,
117
+ ok: false,
118
+ error: {
119
+ message: 'Failed to fetch',
120
+ body: error,
121
+ },
122
+ };
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+ async parseResponse(res) {
128
+ const contentType = res.headers.get('content-type') || '';
129
+ if (contentType.includes('application/json')) {
130
+ return res.json();
131
+ }
132
+ if (contentType.includes('text/')) {
133
+ return res.text();
134
+ }
135
+ if (contentType.includes('application/octet-stream') ||
136
+ contentType.includes('image/') ||
137
+ contentType.includes('video/') ||
138
+ contentType.includes('audio/')) {
139
+ return res.blob();
140
+ }
141
+ if (res.body) {
142
+ const text = await res.text();
143
+ return text || null;
144
+ }
145
+ return null;
146
+ }
147
+ // Helper method to build URL with query parameters
148
+ buildUrlWithParams(url, params) {
149
+ if (!params) {
150
+ return url;
151
+ }
152
+ const urlObj = new URL(url, url.startsWith('http') ? undefined : 'http://localhost');
153
+ Object.entries(params).forEach(([key, value]) => {
154
+ if (value !== undefined && value !== null) {
155
+ urlObj.searchParams.set(key, String(value));
156
+ }
157
+ });
158
+ // If the original URL was relative, return just the pathname + search
159
+ if (!url.startsWith('http')) {
160
+ return urlObj.pathname + urlObj.search;
161
+ }
162
+ return urlObj.toString();
163
+ }
164
+ // 🎯 PIT OF SUCCESS: Convenience methods with smart defaults
165
+ /**
166
+ * HEAD request with query parameter support.
167
+ *
168
+ * HEAD requests are used to retrieve metadata about a resource without downloading
169
+ * the response body. Useful for checking if a resource exists, getting content length,
170
+ * last modified date, etc.
171
+ *
172
+ * @template T - Expected response data type (will be null for HEAD requests)
173
+ * @param url - Request URL
174
+ * @param params - Query parameters to append to URL
175
+ * @returns Promise resolving to typed response (data will always be null)
176
+ *
177
+ * @example Check if resource exists:
178
+ * ```typescript
179
+ * const headResponse = await client.head('/api/large-file.zip');
180
+ * if (headResponse.ok) {
181
+ * const contentLength = headResponse.headers.get('content-length');
182
+ * const lastModified = headResponse.headers.get('last-modified');
183
+ * console.log(`File size: ${contentLength} bytes`);
184
+ * }
185
+ * ```
186
+ *
187
+ * @example Check with query parameters:
188
+ * ```typescript
189
+ * const exists = await client.head('/api/users', { id: 123 });
190
+ * if (exists.status === 404) {
191
+ * console.log('User not found');
192
+ * }
193
+ * ```
194
+ */
195
+ head(url, params) {
196
+ const finalUrl = this.buildUrlWithParams(url, params);
197
+ return this.request(finalUrl, { method: 'HEAD' });
198
+ }
199
+ /**
200
+ * HEAD request that returns useful metadata about a resource.
201
+ *
202
+ * This is a convenience method that extracts common metadata from HEAD responses
203
+ * for easier consumption.
204
+ *
205
+ * @param url - Request URL
206
+ * @param params - Query parameters to append to URL
207
+ * @returns Promise resolving to response with extracted metadata
208
+ *
209
+ * @example Get resource metadata:
210
+ * ```typescript
211
+ * const metadata = await client.headMetadata('/api/large-file.zip');
212
+ * if (metadata.ok) {
213
+ * console.log('File exists:', metadata.exists);
214
+ * console.log('Content type:', metadata.contentType);
215
+ * console.log('Size:', metadata.contentLength, 'bytes');
216
+ * console.log('Last modified:', metadata.lastModified);
217
+ * }
218
+ * ```
219
+ */
220
+ async headMetadata(url, params) {
221
+ const response = await this.head(url, params);
222
+ const contentLengthHeader = response.headers.get('content-length');
223
+ const lastModifiedHeader = response.headers.get('last-modified');
224
+ return {
225
+ ...response,
226
+ exists: response.ok,
227
+ contentType: response.headers.get('content-type') || undefined,
228
+ contentLength: contentLengthHeader ? parseInt(contentLengthHeader, 10) : undefined,
229
+ lastModified: lastModifiedHeader ? new Date(lastModifiedHeader) : undefined,
230
+ etag: response.headers.get('etag') || undefined,
231
+ cacheControl: response.headers.get('cache-control') || undefined,
232
+ };
233
+ }
234
+ /**
235
+ * GET request with query parameter support.
236
+ *
237
+ * @template T - Expected response data type
238
+ * @param url - Request URL
239
+ * @param params - Query parameters to append to URL
240
+ * @returns Promise resolving to typed response
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * const users = await client.get<User[]>('/api/users');
245
+ * const filteredUsers = await client.get<User[]>('/api/users', { status: 'active', limit: 10 });
246
+ * if (users.ok) console.log(users.data);
247
+ * ```
248
+ */
249
+ get(url, params) {
250
+ const finalUrl = this.buildUrlWithParams(url, params);
251
+ return this.request(finalUrl, { method: 'GET' });
252
+ }
253
+ /**
254
+ * POST request with automatic JSON serialization.
255
+ *
256
+ * @template T - Expected response data type
257
+ * @param url - Request URL
258
+ * @param body - Request body (auto-serialized to JSON)
259
+ * @param headers - Additional headers (Content-Type: application/json is default)
260
+ * @returns Promise resolving to typed response
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * const result = await client.post<User>('/api/users', { name: 'John' });
265
+ * ```
266
+ */
267
+ post(url, body, headers) {
268
+ const requestHeaders = {
269
+ 'Content-Type': 'application/json',
270
+ ...(headers ?? {}),
271
+ };
272
+ return this.request(url, {
273
+ method: 'POST',
274
+ headers: requestHeaders,
275
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
276
+ });
277
+ }
278
+ /**
279
+ * PUT request with automatic JSON serialization.
280
+ *
281
+ * @template T - Expected response data type
282
+ * @param url - Request URL
283
+ * @param body - Request body (auto-serialized to JSON)
284
+ * @param headers - Additional headers (Content-Type: application/json is default)
285
+ * @returns Promise resolving to typed response
286
+ */
287
+ put(url, body, headers) {
288
+ const requestHeaders = {
289
+ 'Content-Type': 'application/json',
290
+ ...(headers ?? {}),
291
+ };
292
+ return this.request(url, {
293
+ method: 'PUT',
294
+ headers: requestHeaders,
295
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
296
+ });
297
+ }
298
+ /**
299
+ * PATCH request with automatic JSON serialization.
300
+ *
301
+ * @template T - Expected response data type
302
+ * @param url - Request URL
303
+ * @param body - Request body (auto-serialized to JSON)
304
+ * @param headers - Additional headers (Content-Type: application/json is default)
305
+ * @returns Promise resolving to typed response
306
+ */
307
+ patch(url, body, headers) {
308
+ const requestHeaders = {
309
+ 'Content-Type': 'application/json',
310
+ ...(headers ?? {}),
311
+ };
312
+ return this.request(url, {
313
+ method: 'PATCH',
314
+ headers: requestHeaders,
315
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
316
+ });
317
+ }
318
+ /**
319
+ * DELETE request with query parameter support.
320
+ *
321
+ * @template T - Expected response data type
322
+ * @param url - Request URL
323
+ * @param params - Query parameters to append to URL
324
+ * @returns Promise resolving to typed response
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * const result = await client.del('/api/users/123');
329
+ * const bulkResult = await client.del('/api/users', { status: 'inactive', force: true });
330
+ * if (result.ok) console.log('Deleted successfully');
331
+ * ```
332
+ */
333
+ del(url, params) {
334
+ const finalUrl = this.buildUrlWithParams(url, params);
335
+ return this.request(finalUrl, { method: 'DELETE' });
336
+ }
337
+ }
338
+ exports.FetchClient = FetchClient;
339
+ //# sourceMappingURL=fetch-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-client.js","sourceRoot":"","sources":["../../../src/client/fetch-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Client module exports - "Pit of Success" design.
3
+ *
4
+ * This module provides a clean, discoverable API:
5
+ * 🎯 Level 1: FetchClient class (what 90% of users need)
6
+ * 🎯 Level 2: Types for TypeScript users (auto-discovered via IntelliSense)
7
+ */
8
+ export { FetchClient } from './fetch-client';
9
+ export type { FetchMiddleware } from './fetch-client';
10
+ export type { FetchResponse, FetchClientOptions } from './types';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Client module exports - "Pit of Success" design.
4
+ *
5
+ * This module provides a clean, discoverable API:
6
+ * 🎯 Level 1: FetchClient class (what 90% of users need)
7
+ * 🎯 Level 2: Types for TypeScript users (auto-discovered via IntelliSense)
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FetchClient = void 0;
11
+ // 🎯 LEVEL 1: Main client class - the "pit of success" entry point
12
+ var fetch_client_1 = require("./fetch-client");
13
+ Object.defineProperty(exports, "FetchClient", { enumerable: true, get: function () { return fetch_client_1.FetchClient; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,mEAAmE;AACnE,+CAA6C;AAApC,2GAAA,WAAW,OAAA"}