kinetex 0.0.2 → 1.0.0-rc.2

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/LICENSE +16 -4
  2. package/README.md +2434 -701
  3. package/dist/browser/kinetex.esm.js +86 -0
  4. package/dist/browser/kinetex.js +19056 -1999
  5. package/dist/browser/kinetex.min.js +85 -8
  6. package/dist/cjs/aws-sigv4.js +903 -0
  7. package/dist/cjs/cache.js +1099 -0
  8. package/dist/cjs/circuit-breaker.js +362 -0
  9. package/dist/cjs/client.js +2890 -0
  10. package/dist/cjs/cookie-parser.js +2182 -0
  11. package/dist/cjs/cookie-store.js +783 -0
  12. package/dist/cjs/cookiejar.js +175 -0
  13. package/dist/cjs/core.js +1267 -0
  14. package/dist/cjs/dedup.js +267 -0
  15. package/dist/cjs/digest.js +552 -0
  16. package/dist/cjs/graphql.js +1086 -0
  17. package/dist/cjs/headers.js +2264 -0
  18. package/dist/cjs/interceptors.js +1115 -0
  19. package/dist/cjs/lifecycle.js +886 -0
  20. package/dist/cjs/logging.js +887 -0
  21. package/dist/cjs/mod.js +98 -0
  22. package/dist/cjs/package.json +1 -3
  23. package/dist/cjs/pagination.js +535 -0
  24. package/dist/cjs/progress.js +694 -0
  25. package/dist/cjs/response.js +1212 -0
  26. package/dist/cjs/socks5.js +681 -0
  27. package/dist/cjs/sse.js +827 -0
  28. package/dist/cjs/types.js +217 -0
  29. package/dist/cjs/url.js +1269 -0
  30. package/dist/cjs/utils.js +901 -0
  31. package/dist/cjs/worker.js +56 -0
  32. package/dist/cjs/ws.js +1099 -0
  33. package/dist/esm/aws-sigv4.js +904 -0
  34. package/dist/esm/aws-sigv4.js.map +1 -0
  35. package/dist/esm/cache.js +1100 -0
  36. package/dist/esm/cache.js.map +1 -0
  37. package/dist/esm/circuit-breaker.js +363 -0
  38. package/dist/esm/circuit-breaker.js.map +1 -0
  39. package/dist/esm/client.js +2891 -0
  40. package/dist/esm/client.js.map +1 -0
  41. package/dist/esm/cookie-parser.js +2183 -0
  42. package/dist/esm/cookie-parser.js.map +1 -0
  43. package/dist/esm/cookie-store.js +784 -0
  44. package/dist/esm/cookie-store.js.map +1 -0
  45. package/dist/esm/cookiejar.js +176 -0
  46. package/dist/esm/cookiejar.js.map +1 -0
  47. package/dist/esm/core.js +1268 -0
  48. package/dist/esm/core.js.map +1 -0
  49. package/dist/esm/dedup.js +268 -0
  50. package/dist/esm/dedup.js.map +1 -0
  51. package/dist/esm/digest.js +553 -0
  52. package/dist/esm/digest.js.map +1 -0
  53. package/dist/esm/graphql.js +1087 -0
  54. package/dist/esm/graphql.js.map +1 -0
  55. package/dist/esm/headers.js +2265 -0
  56. package/dist/esm/headers.js.map +1 -0
  57. package/dist/esm/interceptors.js +1116 -0
  58. package/dist/esm/interceptors.js.map +1 -0
  59. package/dist/esm/lifecycle.js +887 -0
  60. package/dist/esm/lifecycle.js.map +1 -0
  61. package/dist/esm/logging.js +888 -0
  62. package/dist/esm/logging.js.map +1 -0
  63. package/dist/esm/mod.js +99 -0
  64. package/dist/esm/mod.js.map +1 -0
  65. package/dist/esm/package.json +1 -0
  66. package/dist/esm/pagination.js +536 -0
  67. package/dist/esm/pagination.js.map +1 -0
  68. package/dist/esm/progress.js +695 -0
  69. package/dist/esm/progress.js.map +1 -0
  70. package/dist/esm/response.js +1213 -0
  71. package/dist/esm/response.js.map +1 -0
  72. package/dist/esm/socks5.js +682 -0
  73. package/dist/esm/socks5.js.map +1 -0
  74. package/dist/esm/sse.js +828 -0
  75. package/dist/esm/sse.js.map +1 -0
  76. package/dist/esm/types.js +218 -0
  77. package/dist/esm/types.js.map +1 -0
  78. package/dist/esm/url.js +1270 -0
  79. package/dist/esm/url.js.map +1 -0
  80. package/dist/esm/utils.js +902 -0
  81. package/dist/esm/utils.js.map +1 -0
  82. package/dist/esm/worker.js +57 -0
  83. package/dist/esm/worker.js.map +1 -0
  84. package/dist/esm/ws.js +1100 -0
  85. package/dist/esm/ws.js.map +1 -0
  86. package/dist/types/aws-sigv4.d.ts +382 -0
  87. package/dist/types/aws-sigv4.d.ts.map +1 -0
  88. package/dist/types/cache.d.ts +397 -0
  89. package/dist/types/cache.d.ts.map +1 -0
  90. package/dist/types/circuit-breaker.d.ts +241 -0
  91. package/dist/types/circuit-breaker.d.ts.map +1 -0
  92. package/dist/types/client.d.ts +616 -0
  93. package/dist/types/client.d.ts.map +1 -0
  94. package/dist/types/cookie-parser.d.ts +203 -0
  95. package/dist/types/cookie-parser.d.ts.map +1 -0
  96. package/dist/types/cookie-store.d.ts +316 -0
  97. package/dist/types/cookie-store.d.ts.map +1 -0
  98. package/dist/types/cookiejar.d.ts +165 -0
  99. package/dist/types/cookiejar.d.ts.map +1 -0
  100. package/dist/types/core.d.ts +297 -0
  101. package/dist/types/core.d.ts.map +1 -0
  102. package/dist/types/dedup.d.ts +164 -0
  103. package/dist/types/dedup.d.ts.map +1 -0
  104. package/dist/types/digest.d.ts +136 -0
  105. package/dist/types/digest.d.ts.map +1 -0
  106. package/dist/types/graphql.d.ts +530 -0
  107. package/dist/types/graphql.d.ts.map +1 -0
  108. package/dist/types/headers.d.ts +1119 -0
  109. package/dist/types/headers.d.ts.map +1 -0
  110. package/dist/types/interceptors.d.ts +681 -0
  111. package/dist/types/interceptors.d.ts.map +1 -0
  112. package/dist/types/lifecycle.d.ts +553 -0
  113. package/dist/types/lifecycle.d.ts.map +1 -0
  114. package/dist/types/logging.d.ts +518 -0
  115. package/dist/types/logging.d.ts.map +1 -0
  116. package/dist/types/mod.d.ts +92 -0
  117. package/dist/types/mod.d.ts.map +1 -0
  118. package/dist/types/pagination.d.ts +401 -0
  119. package/dist/types/pagination.d.ts.map +1 -0
  120. package/dist/types/progress.d.ts +344 -0
  121. package/dist/types/progress.d.ts.map +1 -0
  122. package/dist/types/response.d.ts +484 -0
  123. package/dist/types/response.d.ts.map +1 -0
  124. package/dist/types/socks5.d.ts +218 -0
  125. package/dist/types/socks5.d.ts.map +1 -0
  126. package/dist/types/sse.d.ts +399 -0
  127. package/dist/types/sse.d.ts.map +1 -0
  128. package/dist/types/types.d.ts +967 -0
  129. package/dist/types/types.d.ts.map +1 -0
  130. package/dist/types/url.d.ts +530 -0
  131. package/dist/types/url.d.ts.map +1 -0
  132. package/dist/types/utils.d.ts +300 -0
  133. package/dist/types/utils.d.ts.map +1 -0
  134. package/dist/types/worker.d.ts +55 -0
  135. package/dist/types/worker.d.ts.map +1 -0
  136. package/dist/types/ws.d.ts +480 -0
  137. package/dist/types/ws.d.ts.map +1 -0
  138. package/package.json +194 -127
  139. package/CHANGELOG.md +0 -50
  140. package/SECURITY.md +0 -31
  141. package/dist/browser/kinetex.cjs.js +0 -9
  142. package/dist/browser/kinetex.esm.min.js +0 -9
  143. package/dist/browser/kinetex.js.map +0 -7
  144. package/dist/cjs/auth/index.cjs +0 -333
  145. package/dist/cjs/auth/index.d.cts +0 -41
  146. package/dist/cjs/auth/index.d.ts.map +0 -1
  147. package/dist/cjs/auth/index.js.map +0 -1
  148. package/dist/cjs/core/chain.cjs +0 -127
  149. package/dist/cjs/core/chain.d.cts +0 -44
  150. package/dist/cjs/core/chain.d.ts.map +0 -1
  151. package/dist/cjs/core/chain.js.map +0 -1
  152. package/dist/cjs/core/transport.cjs +0 -544
  153. package/dist/cjs/core/transport.d.cts +0 -11
  154. package/dist/cjs/core/transport.d.ts.map +0 -1
  155. package/dist/cjs/core/transport.js.map +0 -1
  156. package/dist/cjs/core/types.cjs +0 -54
  157. package/dist/cjs/core/types.d.cts +0 -322
  158. package/dist/cjs/core/types.d.ts.map +0 -1
  159. package/dist/cjs/core/types.js.map +0 -1
  160. package/dist/cjs/index.cjs +0 -272
  161. package/dist/cjs/index.d.cts +0 -12
  162. package/dist/cjs/index.d.ts.map +0 -1
  163. package/dist/cjs/index.js.map +0 -1
  164. package/dist/cjs/middleware/pipeline.cjs +0 -451
  165. package/dist/cjs/middleware/pipeline.d.cts +0 -32
  166. package/dist/cjs/middleware/pipeline.d.ts.map +0 -1
  167. package/dist/cjs/middleware/pipeline.js.map +0 -1
  168. package/dist/cjs/plugins/cookies.cjs +0 -192
  169. package/dist/cjs/plugins/cookies.d.cts +0 -57
  170. package/dist/cjs/plugins/cookies.d.ts.map +0 -1
  171. package/dist/cjs/plugins/cookies.js.map +0 -1
  172. package/dist/cjs/plugins/extras.cjs +0 -316
  173. package/dist/cjs/plugins/extras.d.cts +0 -87
  174. package/dist/cjs/plugins/extras.d.ts.map +0 -1
  175. package/dist/cjs/plugins/extras.js.map +0 -1
  176. package/dist/cjs/plugins/index.cjs +0 -18
  177. package/dist/cjs/plugins/index.d.cts +0 -7
  178. package/dist/cjs/plugins/index.d.ts.map +0 -1
  179. package/dist/cjs/plugins/index.js.map +0 -1
  180. package/dist/cjs/plugins/proxy.cjs +0 -161
  181. package/dist/cjs/plugins/proxy.d.cts +0 -25
  182. package/dist/cjs/plugins/proxy.d.ts.map +0 -1
  183. package/dist/cjs/plugins/proxy.js.map +0 -1
  184. package/dist/cjs/utils/index.cjs +0 -12
  185. package/dist/cjs/utils/index.d.cts +0 -6
  186. package/dist/cjs/utils/index.d.ts.map +0 -1
  187. package/dist/cjs/utils/index.js.map +0 -1
  188. package/dist/esm/auth/index.js +0 -324
  189. package/dist/esm/auth/index.js.map +0 -1
  190. package/dist/esm/core/chain.js +0 -123
  191. package/dist/esm/core/chain.js.map +0 -1
  192. package/dist/esm/core/transport.js +0 -536
  193. package/dist/esm/core/transport.js.map +0 -1
  194. package/dist/esm/core/types.js +0 -46
  195. package/dist/esm/core/types.js.map +0 -1
  196. package/dist/esm/index.js +0 -241
  197. package/dist/esm/index.js.map +0 -1
  198. package/dist/esm/middleware/pipeline.js +0 -438
  199. package/dist/esm/middleware/pipeline.js.map +0 -1
  200. package/dist/esm/plugins/cookies.js +0 -187
  201. package/dist/esm/plugins/cookies.js.map +0 -1
  202. package/dist/esm/plugins/extras.js +0 -306
  203. package/dist/esm/plugins/extras.js.map +0 -1
  204. package/dist/esm/plugins/index.js +0 -4
  205. package/dist/esm/plugins/index.js.map +0 -1
  206. package/dist/esm/plugins/proxy.js +0 -124
  207. package/dist/esm/plugins/proxy.js.map +0 -1
  208. package/dist/esm/utils/index.js +0 -6
  209. package/dist/esm/utils/index.js.map +0 -1
  210. package/dist/types/auth/index.d.ts +0 -41
  211. package/dist/types/auth/index.d.ts.map +0 -1
  212. package/dist/types/core/chain.d.ts +0 -44
  213. package/dist/types/core/chain.d.ts.map +0 -1
  214. package/dist/types/core/transport.d.ts +0 -11
  215. package/dist/types/core/transport.d.ts.map +0 -1
  216. package/dist/types/core/types.d.ts +0 -322
  217. package/dist/types/core/types.d.ts.map +0 -1
  218. package/dist/types/index.d.ts +0 -12
  219. package/dist/types/index.d.ts.map +0 -1
  220. package/dist/types/middleware/pipeline.d.ts +0 -32
  221. package/dist/types/middleware/pipeline.d.ts.map +0 -1
  222. package/dist/types/plugins/cookies.d.ts +0 -57
  223. package/dist/types/plugins/cookies.d.ts.map +0 -1
  224. package/dist/types/plugins/extras.d.ts +0 -87
  225. package/dist/types/plugins/extras.d.ts.map +0 -1
  226. package/dist/types/plugins/index.d.ts +0 -7
  227. package/dist/types/plugins/index.d.ts.map +0 -1
  228. package/dist/types/plugins/proxy.d.ts +0 -25
  229. package/dist/types/plugins/proxy.d.ts.map +0 -1
  230. package/dist/types/utils/index.d.ts +0 -6
  231. package/dist/types/utils/index.d.ts.map +0 -1
@@ -0,0 +1,681 @@
1
+ /**
2
+ * interceptors.ts
3
+ *
4
+ * Cross-runtime HTTP interceptor pipeline.
5
+ *
6
+ * Runtimes: Deno · Bun · Node.js · Cloudflare Workers · Vercel Edge ·
7
+ * AWS Lambda · Browser · any WinterCG-compatible runtime.
8
+ *
9
+ * Features:
10
+ * - Request interceptors (mutate, replace, abort before sending)
11
+ * - Response interceptors (mutate, retry, transform body)
12
+ * - Error interceptors (recover, rethrow, classify)
13
+ * - Named interceptors (register, eject by ID)
14
+ * - Priority ordering (lower number = runs first)
15
+ * - Async-first pipeline (every hook is async-capable)
16
+ * - Scoped interceptors (per-instance, not global)
17
+ * - One-shot interceptors (auto-eject after first run)
18
+ * - Conditional interceptors (predicate-gated execution)
19
+ * - Retry interceptor (exponential back-off, jitter, per-status config)
20
+ * - Auth interceptor (Bearer injection + token refresh + queue)
21
+ * - Logging interceptor (structured, redaction-aware)
22
+ * - Timeout interceptor (per-request deadline with AbortSignal)
23
+ * - Cache interceptor (in-memory LRU, stale-while-revalidate)
24
+ * - Dedupe interceptor (coalesce identical in-flight requests)
25
+ * - Rate-limit interceptor (token bucket, respect Retry-After)
26
+ * - HAR interceptor (record HTTP Archive entries)
27
+ * - Metrics interceptor (timing, status buckets, error rates)
28
+ * - No dependencies, no runtime globals beyond Promise/Map/Set
29
+ */
30
+ /** Normalized request passed through the pipeline. */
31
+ export interface InterceptorRequest {
32
+ /** Target URL */
33
+ url: string;
34
+ /** HTTP method (GET, POST, etc.) */
35
+ method: string;
36
+ /** Request headers as a flat object */
37
+ headers: Record<string, string>;
38
+ /** Request body */
39
+ body: BodyInit | null;
40
+ /** AbortSignal for cancellation (may be null) */
41
+ signal: AbortSignal | null;
42
+ /**
43
+ * Arbitrary per-request metadata bag — interceptors may read/write freely.
44
+ * Simple string-keyed values for request-scoped data.
45
+ *
46
+ * Use `meta` for:
47
+ * - Request-specific data (e.g., user ID, request ID)
48
+ * - Simple configuration passed between interceptors
49
+ *
50
+ * Use `ctx.store` (Map<symbol,>) for:
51
+ * - Complex objects requiring Symbol keys
52
+ * - Pipeline-scoped data shared across request/response/error phases
53
+ * - Avoiding key collisions with other interceptors
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * // In request interceptor:
58
+ * ctx.request.meta.userId = "123";
59
+ *
60
+ * // In response interceptor:
61
+ * const userId = ctx.request.meta.userId;
62
+ * ```
63
+ */
64
+ meta: Record<string, unknown>;
65
+ }
66
+ /** Normalized response passed through the pipeline. */
67
+ export interface InterceptorResponse {
68
+ /** HTTP status code */
69
+ status: number;
70
+ /** HTTP status text (e.g. "OK") */
71
+ statusText: string;
72
+ /** Response headers as a flat object */
73
+ headers: Record<string, string>;
74
+ /** Response body as string or binary */
75
+ body: string | Uint8Array | null;
76
+ /** Original runtime response (fetch Response, node http.IncomingMessage, etc.) */
77
+ raw: unknown;
78
+ /** Reference back to the request that produced this response */
79
+ request: InterceptorRequest;
80
+ }
81
+ /** Context object threaded through the entire pipeline for one request. */
82
+ export interface InterceptorContext {
83
+ /** Mutable request — interceptors modify this in place */
84
+ request: InterceptorRequest;
85
+ /** Set by the dispatcher when the response arrives */
86
+ response: InterceptorResponse | null;
87
+ /** Set when an error occurs at any stage */
88
+ error: unknown | null;
89
+ /** Monotonic start time (performance.now() or Date.now()) */
90
+ startedAt: number;
91
+ /** Attempt counter, incremented by retry interceptor */
92
+ attempt: number;
93
+ /** Whether the pipeline has been aborted */
94
+ aborted: boolean;
95
+ /**
96
+ * Shared pipeline-scoped storage for cross-interceptor communication.
97
+ * Use Symbols as keys to avoid conflicts.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const MY_KEY = Symbol("myKey");
102
+ * ctx.store.set(MY_KEY, { computed: true });
103
+ * // Later interceptor:
104
+ * const data = ctx.store.get(MY_KEY);
105
+ * ```
106
+ *
107
+ * @see meta For per-request metadata (simpler key-value store)
108
+ */
109
+ store: Map<symbol, unknown>;
110
+ }
111
+ /**
112
+ * A request interceptor may:
113
+ * - return void / undefined → pass the (possibly mutated) request through
114
+ * - return InterceptorRequest → replace the request entirely
115
+ * - return InterceptorResponse → short-circuit; skip the actual fetch
116
+ * - throw → abort the pipeline with that error
117
+ */
118
+ export type RequestInterceptorResult = void | undefined | InterceptorRequest | InterceptorResponse;
119
+ /**
120
+ * A response interceptor may:
121
+ * - return void / undefined → pass through
122
+ * - return InterceptorResponse → replace the response
123
+ * - return InterceptorRequest → retry (pipeline re-runs from dispatch)
124
+ * - throw → convert to error pipeline
125
+ */
126
+ export type ResponseInterceptorResult = void | undefined | InterceptorResponse | InterceptorRequest;
127
+ /**
128
+ * An error interceptor may:
129
+ * - return void / undefined → rethrow the error
130
+ * - return InterceptorResponse → recover with synthetic response
131
+ * - throw → replace with a different error
132
+ */
133
+ export type ErrorInterceptorResult = void | undefined | InterceptorResponse;
134
+ /** Generic interceptor function type (internal use). */
135
+ export type InterceptorFn<T = unknown> = (ctx: InterceptorContext) => Promise<T> | T;
136
+ /** A request-phase interceptor function. */
137
+ export type RequestInterceptorFn = (ctx: InterceptorContext) => Promise<RequestInterceptorResult> | RequestInterceptorResult;
138
+ /** A response-phase interceptor function. */
139
+ export type ResponseInterceptorFn = (ctx: InterceptorContext) => Promise<ResponseInterceptorResult> | ResponseInterceptorResult;
140
+ /** An error-phase interceptor function. */
141
+ export type ErrorInterceptorFn = (ctx: InterceptorContext) => Promise<ErrorInterceptorResult> | ErrorInterceptorResult;
142
+ /** A registered request interceptor. */
143
+ export interface RequestInterceptor {
144
+ /** Unique identifier used for ejection. */
145
+ id: string;
146
+ /** Execution priority (lower = runs first). */
147
+ priority: number;
148
+ /** Auto-eject after first execution. */
149
+ once: boolean;
150
+ /** Optional predicate gate — interceptor is skipped if false. */
151
+ condition: ((ctx: InterceptorContext) => boolean) | null;
152
+ /** The interceptor function. */
153
+ fn: RequestInterceptorFn;
154
+ }
155
+ /** A registered response interceptor. */
156
+ export interface ResponseInterceptor {
157
+ /** Unique identifier used for ejection. */
158
+ id: string;
159
+ /** Execution priority (lower = runs first). */
160
+ priority: number;
161
+ /** Auto-eject after first execution. */
162
+ once: boolean;
163
+ /** Optional predicate gate — interceptor is skipped if false. */
164
+ condition: ((ctx: InterceptorContext) => boolean) | null;
165
+ /** The interceptor function. */
166
+ fn: ResponseInterceptorFn;
167
+ }
168
+ /** A registered error interceptor. */
169
+ export interface ErrorInterceptor {
170
+ /** Unique identifier used for ejection. */
171
+ id: string;
172
+ /** Execution priority (lower = runs first). */
173
+ priority: number;
174
+ /** Auto-eject after first execution. */
175
+ once: boolean;
176
+ /** Optional predicate gate — interceptor is skipped if false. */
177
+ condition: ((ctx: InterceptorContext) => boolean) | null;
178
+ /** The interceptor function. */
179
+ fn: ErrorInterceptorFn;
180
+ }
181
+ export interface InterceptorOptions {
182
+ /** Unique ID. Auto-generated if omitted. */
183
+ id?: string;
184
+ /**
185
+ * Execution order. Lower = earlier.
186
+ * Request interceptors: lower priority runs first (outbound).
187
+ * Response interceptors: lower priority runs first (inbound).
188
+ * Default: 0
189
+ */
190
+ priority?: number;
191
+ /** If true, auto-eject after first successful execution. */
192
+ once?: boolean;
193
+ /** Only run if this predicate returns true. */
194
+ condition?: (ctx: InterceptorContext) => boolean;
195
+ }
196
+ /**
197
+ * The function that actually sends the HTTP request.
198
+ * The pipeline calls this once (unless a retry interceptor resets the context).
199
+ */
200
+ export type Dispatcher = (req: InterceptorRequest) => Promise<InterceptorResponse>;
201
+ /**
202
+ * Manages registration, ejection, and pipeline execution of interceptors.
203
+ *
204
+ * Interceptors are executed in priority order (lowest first) through three
205
+ * phases: request (outbound), response (inbound), and error (recovery).
206
+ */
207
+ export declare class InterceptorManager {
208
+ private requestInterceptors;
209
+ private responseInterceptors;
210
+ private errorInterceptors;
211
+ /**
212
+ * Register a request interceptor.
213
+ *
214
+ * @param fn - Interceptor function
215
+ * @param opts - Registration options (id, priority, once, condition)
216
+ * @returns The interceptor ID (auto-generated or from opts.id)
217
+ */
218
+ useRequest(fn: RequestInterceptorFn, opts?: InterceptorOptions): string;
219
+ /**
220
+ * Register a response interceptor.
221
+ *
222
+ * @param fn - Interceptor function
223
+ * @param opts - Registration options (id, priority, once, condition)
224
+ * @returns The interceptor ID (auto-generated or from opts.id)
225
+ */
226
+ useResponse(fn: ResponseInterceptorFn, opts?: InterceptorOptions): string;
227
+ /**
228
+ * Register an error interceptor.
229
+ *
230
+ * @param fn - Interceptor function
231
+ * @param opts - Registration options (id, priority, once, condition)
232
+ * @returns The interceptor ID (auto-generated or from opts.id)
233
+ */
234
+ useError(fn: ErrorInterceptorFn, opts?: InterceptorOptions): string;
235
+ /** Register both request and response interceptors together. */
236
+ use(requestFn: RequestInterceptorFn | null, responseFn: ResponseInterceptorFn | null, opts?: InterceptorOptions): {
237
+ /** ID of the registered request interceptor, or null */
238
+ requestId: string | null;
239
+ /** ID of the registered response interceptor, or null */
240
+ responseId: string | null;
241
+ };
242
+ /**
243
+ * Eject (remove) an interceptor by ID.
244
+ *
245
+ * @param id - The interceptor ID returned from registration
246
+ * @returns `true` if an interceptor was found and removed
247
+ */
248
+ eject(id: string): boolean;
249
+ /** Remove all registered interceptors. */
250
+ ejectAll(): void;
251
+ /** Check if an interceptor with the given ID is registered. */
252
+ has(id: string): boolean;
253
+ /** Number of registered request interceptors. */
254
+ get requestCount(): number;
255
+ /** Number of registered response interceptors. */
256
+ get responseCount(): number;
257
+ /** Number of registered error interceptors. */
258
+ get errorCount(): number;
259
+ /**
260
+ * Execute the full interceptor pipeline for a single request.
261
+ *
262
+ * @param request - Initial request to send
263
+ * @param dispatcher - The function that performs the actual HTTP fetch
264
+ * @returns The final response after all interceptors have run
265
+ */
266
+ execute(request: InterceptorRequest, dispatcher: Dispatcher): Promise<InterceptorResponse>;
267
+ /** Internal: run (or re-run on retry) the full pipeline. */
268
+ _run(ctx: InterceptorContext, dispatcher: Dispatcher): Promise<InterceptorResponse>;
269
+ private _runResponsePhase;
270
+ private _runErrorPhase;
271
+ }
272
+ export interface RetryConfig {
273
+ /** Maximum number of retry attempts (default: 3) */
274
+ maxRetries: number;
275
+ /** Base delay in ms for exponential back-off (default: 300) */
276
+ baseDelayMs: number;
277
+ /** Maximum delay cap in ms (default: 30_000) */
278
+ maxDelayMs: number;
279
+ /** Jitter factor 0–1 (default: 0.3) */
280
+ jitter: number;
281
+ /** HTTP status codes that trigger a retry (default: [408,429,500,502,503,504]) */
282
+ retryStatuses: number[];
283
+ /** Retry on network errors / aborts (default: true) */
284
+ retryOnError: boolean;
285
+ /** Only retry these methods (default: GET, HEAD, PUT, DELETE, OPTIONS, TRACE) */
286
+ retryMethods: string[];
287
+ /**
288
+ * Custom predicate — if provided, overrides retryStatuses + retryOnError.
289
+ * Return true to retry, false to not retry.
290
+ */
291
+ shouldRetry: ((ctx: InterceptorContext) => boolean) | null;
292
+ /**
293
+ * Called before each retry with the upcoming delay in ms.
294
+ * Useful for logging.
295
+ */
296
+ onRetry: ((ctx: InterceptorContext, delayMs: number) => void) | null;
297
+ }
298
+ /**
299
+ * Create a retry interceptor pair (response + error) with exponential back-off,
300
+ * jitter, and per-status-code configuration.
301
+ *
302
+ * @param config - Retry configuration (defaults used for omitted fields)
303
+ */
304
+ export declare function createRetryInterceptor(config?: Partial<RetryConfig>): {
305
+ /** Triggers retries for responses with retryable status codes */
306
+ responseInterceptor: ResponseInterceptorFn;
307
+ /** Triggers retries when a request fails with a retryable error */
308
+ errorInterceptor: ErrorInterceptorFn;
309
+ };
310
+ export interface AuthInterceptorConfig {
311
+ /** Return the current access token. */
312
+ getToken: () => string | null | Promise<string | null>;
313
+ /**
314
+ * Called when a 401 is received. Should refresh and return the new token,
315
+ * or null/throw to propagate the 401.
316
+ */
317
+ refreshToken: (() => Promise<string | null>) | null;
318
+ /** Header to inject the token into (default: "authorization") */
319
+ headerName: string;
320
+ /** Scheme prefix (default: "Bearer ") */
321
+ scheme: string;
322
+ /** Status codes that trigger a refresh attempt (default: [401]) */
323
+ refreshOnStatuses: number[];
324
+ /** Max concurrent refresh queue size (default: 50) */
325
+ maxQueue: number;
326
+ /**
327
+ * Circuit breaker: minimum delay between failed refresh attempts (default: 30000ms).
328
+ * If refresh fails, subsequent requests will throw until this delay has passed.
329
+ */
330
+ refreshRetryDelay: number;
331
+ }
332
+ /**
333
+ * Create an auth interceptor pair (request + response) that injects Bearer
334
+ * tokens and handles 401-driven token refresh with request queueing and
335
+ * circuit-breaker.
336
+ *
337
+ * @param config - Auth configuration (must include `getToken`; `refreshToken`
338
+ * and other fields are optional)
339
+ */
340
+ export declare function createAuthInterceptor(config: Partial<AuthInterceptorConfig> & {
341
+ getToken: () => string | null | Promise<string | null>;
342
+ }): {
343
+ /** Injects the current token into outgoing request headers */
344
+ requestInterceptor: RequestInterceptorFn;
345
+ /** Handles 401 responses by triggering token refresh and retry */
346
+ responseInterceptor: ResponseInterceptorFn;
347
+ };
348
+ export interface TimeoutConfig {
349
+ /** Default timeout in ms. 0 = disabled. */
350
+ timeoutMs: number;
351
+ /** Per-method overrides, e.g. { POST: 60_000 } */
352
+ methodTimeouts: Record<string, number>;
353
+ /** Error message on timeout */
354
+ message: string;
355
+ }
356
+ /**
357
+ * Create a timeout interceptor that aborts requests exceeding the configured
358
+ * deadline. Cleans up timers in both the response and error phases.
359
+ *
360
+ * @param config - Timeout configuration (defaults used for omitted fields)
361
+ */
362
+ export declare function createTimeoutInterceptor(config?: Partial<TimeoutConfig>): {
363
+ /** Identifier for this timeout interceptor instance */
364
+ id: string;
365
+ /** Attaches an AbortSignal to the request with the configured timeout */
366
+ requestInterceptor: RequestInterceptorFn;
367
+ /** Cleans up the timeout timer after a successful response */
368
+ responseInterceptor: ResponseInterceptorFn;
369
+ /** Cleans up the timeout timer when an error occurs */
370
+ errorInterceptor: ErrorInterceptorFn;
371
+ };
372
+ /** Error thrown when a request exceeds the configured timeout. */
373
+ export declare class TimeoutError extends Error {
374
+ readonly timeoutMs: number;
375
+ readonly code = "ETIMEDOUT";
376
+ constructor(message: string, timeoutMs: number);
377
+ }
378
+ /** A single structured log entry emitted by the logging interceptor. */
379
+ export interface LogEntry {
380
+ /** Phase that triggered the entry */
381
+ type: "request" | "response" | "error";
382
+ /** Unix timestamp when the entry was created */
383
+ timestamp: number;
384
+ /** Unique request identifier */
385
+ requestId: string;
386
+ /** HTTP method */
387
+ method: string;
388
+ /** Request URL */
389
+ url: string;
390
+ /** HTTP status (null for request/error entries) */
391
+ status: number | null;
392
+ /** Elapsed time in ms (null for request entries) */
393
+ durationMs: number | null;
394
+ /** Attempt number (1-based) */
395
+ attempt: number;
396
+ /** Error message (null for request/response entries) */
397
+ error: string | null;
398
+ }
399
+ export interface LoggingConfig {
400
+ /** Called for every log entry. Defaults to console output. */
401
+ logger: (entry: LogEntry) => void;
402
+ /** Header names whose values should be redacted in logs. */
403
+ redactHeaders: string[];
404
+ /** Log request phase (default: true) */
405
+ logRequests: boolean;
406
+ /** Log response phase (default: true) */
407
+ logResponses: boolean;
408
+ /** Log error phase (default: true) */
409
+ logErrors: boolean;
410
+ }
411
+ /**
412
+ * Create a logging interceptor that emits structured log entries for each
413
+ * request, response, and error phase. Sensitive headers can be redacted.
414
+ *
415
+ * @param config - Logging configuration (defaults used for omitted fields)
416
+ */
417
+ export declare function createLoggingInterceptor(config?: Partial<LoggingConfig>): {
418
+ /** Emits a structured log entry when a request is sent */
419
+ requestInterceptor: RequestInterceptorFn;
420
+ /** Emits a structured log entry when a response is received */
421
+ responseInterceptor: ResponseInterceptorFn;
422
+ /** Emits a structured log entry when an error occurs */
423
+ errorInterceptor: ErrorInterceptorFn;
424
+ };
425
+ /** A single entry in the cache store. */
426
+ export interface CacheEntry {
427
+ /** The cached response */
428
+ response: InterceptorResponse;
429
+ /** Timestamp when the entry was created */
430
+ createdAt: number;
431
+ /** Timestamp when the entry expires (fresh until this point) */
432
+ expiresAt: number;
433
+ /** End of the stale-while-revalidate window */
434
+ staleUntil: number;
435
+ /** ETag for conditional revalidation */
436
+ etag: string | null;
437
+ /** Last-Modified date string for conditional revalidation */
438
+ lastModified: string | null;
439
+ }
440
+ export interface CacheConfig {
441
+ /** Maximum number of cached entries (LRU eviction) */
442
+ maxEntries: number;
443
+ /** Default TTL in ms when no Cache-Control is present (default: 60_000) */
444
+ defaultTtlMs: number;
445
+ /** Only cache these methods (default: ["GET", "HEAD"]) */
446
+ cacheMethods: string[];
447
+ /** Custom cache key function */
448
+ cacheKey: ((req: InterceptorRequest) => string) | null;
449
+ /** If false, ignore Cache-Control: no-store / no-cache on response */
450
+ honorCacheControl: boolean;
451
+ }
452
+ /**
453
+ * Create a cache interceptor with LRU eviction and stale-while-revalidate
454
+ * support. Only caches GET and HEAD by default.
455
+ *
456
+ * @param config - Cache configuration (defaults used for omitted fields)
457
+ */
458
+ export declare function createCacheInterceptor(config?: Partial<CacheConfig>): {
459
+ /** Serves cached responses and attaches conditional headers for revalidation */
460
+ requestInterceptor: RequestInterceptorFn;
461
+ /** Caches successful responses and handles 304 revalidation */
462
+ responseInterceptor: ResponseInterceptorFn;
463
+ /** Direct access to the underlying cache store */
464
+ store: Map<string, CacheEntry>;
465
+ };
466
+ /**
467
+ * Create a deduplication interceptor that coalesces concurrent GET/HEAD
468
+ * requests to the same URL into a single fetch.
469
+ */
470
+ export declare function createDedupeInterceptor(): {
471
+ /** Coalesces duplicate in-flight GET/HEAD requests into one */
472
+ requestInterceptor: RequestInterceptorFn;
473
+ /** Resolves queued waiters with the shared response */
474
+ responseInterceptor: ResponseInterceptorFn;
475
+ /** Rejects queued waiters when the shared request fails */
476
+ errorInterceptor: ErrorInterceptorFn;
477
+ };
478
+ export interface RateLimitConfig {
479
+ /** Maximum requests per window */
480
+ limit: number;
481
+ /** Window size in ms (default: 1000 = 1 req/s * limit) */
482
+ windowMs: number;
483
+ /** If true, queue excess requests instead of rejecting (default: true) */
484
+ queue: boolean;
485
+ /** Max queue depth before rejecting (default: 100) */
486
+ maxQueue: number;
487
+ }
488
+ /**
489
+ * Create a rate-limit interceptor using a token bucket algorithm.
490
+ * Excess requests are queued (default) or rejected when the queue is full.
491
+ *
492
+ * @param config - Rate-limit configuration (defaults used for omitted fields)
493
+ */
494
+ export declare function createRateLimitInterceptor(config?: Partial<RateLimitConfig>): RequestInterceptorFn;
495
+ /** Error thrown when the rate limit is exceeded. */
496
+ export declare class RateLimitError extends Error {
497
+ /** Machine-readable error code identifying this as a rate-limit error */
498
+ readonly code = "ERATELIMIT";
499
+ constructor(message: string);
500
+ }
501
+ /** A single HAR (HTTP Archive) entry representing one request/response pair. */
502
+ export interface HAREntry {
503
+ /** ISO 8601 timestamp of the request start */
504
+ startedDateTime: string;
505
+ /** Total round-trip time in ms */
506
+ time: number;
507
+ /** Request details */
508
+ request: {
509
+ /** HTTP method */
510
+ method: string;
511
+ /** Full request URL */
512
+ url: string;
513
+ /** HTTP version string (e.g. "HTTP/1.1") */
514
+ httpVersion: string;
515
+ /** Request headers as name/value pairs */
516
+ headers: Array<{
517
+ name: string;
518
+ value: string;
519
+ }>;
520
+ /** Query string parameters */
521
+ queryString: Array<{
522
+ name: string;
523
+ value: string;
524
+ }>;
525
+ /** Request body size in bytes */
526
+ bodySize: number;
527
+ };
528
+ /** Response details */
529
+ response: {
530
+ /** HTTP status code */
531
+ status: number;
532
+ /** HTTP status text */
533
+ statusText: string;
534
+ /** HTTP version string */
535
+ httpVersion: string;
536
+ /** Response headers as name/value pairs */
537
+ headers: Array<{
538
+ name: string;
539
+ value: string;
540
+ }>;
541
+ /** Response content metadata */
542
+ content: {
543
+ /** Content size in bytes */
544
+ size: number;
545
+ /** MIME type of the response */
546
+ mimeType: string;
547
+ /** Response body text (only for string bodies) */
548
+ text?: string;
549
+ };
550
+ /** Response body size in bytes */
551
+ bodySize: number;
552
+ /** Redirect target URL if applicable */
553
+ redirectURL: string;
554
+ };
555
+ /** Request timing breakdown */
556
+ timings: {
557
+ /** Time spent sending the request in ms */
558
+ send: number;
559
+ /** Time waiting for the response in ms */
560
+ wait: number;
561
+ /** Time receiving the response in ms */
562
+ receive: number;
563
+ };
564
+ }
565
+ /** A top-level HAR log container (HAR 1.2 format). */
566
+ export interface HARLog {
567
+ /** HAR format version */
568
+ version: string;
569
+ /** Tool that created the log */
570
+ creator: {
571
+ name: string;
572
+ version: string;
573
+ };
574
+ /** Array of request/response entries */
575
+ entries: HAREntry[];
576
+ }
577
+ /**
578
+ * Create a HAR (HTTP Archive) recording interceptor.
579
+ * Captures request/response pairs for export as a HAR log.
580
+ */
581
+ export declare function createHARInterceptor(): {
582
+ /** Records the start time for HAR entry timing */
583
+ requestInterceptor: RequestInterceptorFn;
584
+ /** Captures request/response details into the HAR log */
585
+ responseInterceptor: ResponseInterceptorFn;
586
+ /** Returns the recorded HAR log in HAR 1.2 format */
587
+ getHAR: () => HARLog;
588
+ /** Clears all recorded HAR entries */
589
+ clearHAR: () => void;
590
+ };
591
+ /** Snapshot of metrics collected by the metrics interceptor. */
592
+ export interface MetricsSnapshot {
593
+ /** Total requests processed */
594
+ totalRequests: number;
595
+ /** Total errors encountered */
596
+ totalErrors: number;
597
+ /** Total retry attempts */
598
+ totalRetries: number;
599
+ /** Status code buckets ("2xx", "3xx", "4xx", "5xx") */
600
+ statusBuckets: Record<string, number>;
601
+ /** Average request duration in ms */
602
+ avgDurationMs: number;
603
+ /** Median request duration in ms */
604
+ p50DurationMs: number;
605
+ /** 95th percentile duration in ms */
606
+ p95DurationMs: number;
607
+ /** 99th percentile duration in ms */
608
+ p99DurationMs: number;
609
+ }
610
+ /**
611
+ * Create a metrics interceptor that tracks request count, error rate, status
612
+ * code buckets, and duration percentiles.
613
+ */
614
+ export declare function createMetricsInterceptor(): {
615
+ /** Records request start time and increments request counter */
616
+ requestInterceptor: RequestInterceptorFn;
617
+ /** Records response duration and updates status code buckets */
618
+ responseInterceptor: ResponseInterceptorFn;
619
+ /** Increments the error counter on pipeline errors */
620
+ errorInterceptor: ErrorInterceptorFn;
621
+ /** Returns a snapshot of accumulated metrics */
622
+ snapshot: () => MetricsSnapshot;
623
+ /** Resets all metrics counters to zero */
624
+ reset: () => void;
625
+ };
626
+ /** @internal Compute byte size of a request/response body. Exported for testing. */
627
+ export declare function computeBodySize(body: BodyInit | string | Uint8Array | null): number;
628
+ /** All interceptor instances returned by {@link createInterceptorSuite}. */
629
+ export interface FullInterceptorSuite {
630
+ /** The interceptor manager with all built-ins registered. */
631
+ manager: InterceptorManager;
632
+ /** Retry interceptor pair. */
633
+ retry: ReturnType<typeof createRetryInterceptor>;
634
+ /** Auth interceptor pair (null if not configured). */
635
+ auth: ReturnType<typeof createAuthInterceptor> | null;
636
+ /** Timeout interceptor metadata. */
637
+ timeout: {
638
+ id: string;
639
+ };
640
+ /** Logging interceptor triplet. */
641
+ logging: ReturnType<typeof createLoggingInterceptor>;
642
+ /** Cache interceptor with store. */
643
+ cache: ReturnType<typeof createCacheInterceptor>;
644
+ /** Deduplication interceptor triplet. */
645
+ dedupe: ReturnType<typeof createDedupeInterceptor>;
646
+ /** HAR recording interceptor. */
647
+ har: ReturnType<typeof createHARInterceptor>;
648
+ /** Metrics interceptor. */
649
+ metrics: ReturnType<typeof createMetricsInterceptor>;
650
+ }
651
+ /** Configuration options for {@link createInterceptorSuite}. */
652
+ export interface SuiteConfig {
653
+ retry?: Partial<RetryConfig>;
654
+ auth?: Partial<AuthInterceptorConfig> & {
655
+ getToken: () => string | null | Promise<string | null>;
656
+ };
657
+ timeout?: Partial<TimeoutConfig>;
658
+ logging?: Partial<LoggingConfig>;
659
+ cache?: Partial<CacheConfig>;
660
+ rateLimit?: Partial<RateLimitConfig>;
661
+ }
662
+ /**
663
+ * Create a full interceptor suite with all built-in interceptors registered
664
+ * at sensible priority levels:
665
+ *
666
+ * | Priority | Interceptor |
667
+ * |----------|------------------|
668
+ * | -100 | Timeout |
669
+ * | -90 | Rate limit |
670
+ * | -80 | Deduplication |
671
+ * | -70 | Cache |
672
+ * | -50 | Auth |
673
+ * | 50 | Retry |
674
+ * | 90 | Logging |
675
+ * | 95 | HAR |
676
+ * | 100 | Metrics |
677
+ *
678
+ * @param config - Configuration for each built-in interceptor
679
+ */
680
+ export declare function createInterceptorSuite(config?: SuiteConfig): FullInterceptorSuite;
681
+ //# sourceMappingURL=interceptors.d.ts.map