httix-http 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.
@@ -0,0 +1,154 @@
1
+ import { r as HttixPlugin, f as HttixRequestConfig, H as HttixClient } from '../types-DkChbb42.cjs';
2
+
3
+ /**
4
+ * httix — Logger plugin
5
+ *
6
+ * Logs request and response lifecycle events via configurable log levels.
7
+ */
8
+
9
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
10
+ interface LoggerPluginConfig {
11
+ /** Minimum log level (default: 'info') */
12
+ level?: LogLevel;
13
+ /** Custom logger function (default: console) */
14
+ logger?: {
15
+ debug: (...args: unknown[]) => void;
16
+ info: (...args: unknown[]) => void;
17
+ warn: (...args: unknown[]) => void;
18
+ error: (...args: unknown[]) => void;
19
+ };
20
+ /** Whether to log request body (default: false) */
21
+ logRequestBody?: boolean;
22
+ /** Whether to log response body (default: false) */
23
+ logResponseBody?: boolean;
24
+ /** Whether to log request headers (default: false) */
25
+ logRequestHeaders?: boolean;
26
+ /** Whether to log response headers (default: false) */
27
+ logResponseHeaders?: boolean;
28
+ }
29
+ declare function loggerPlugin(config?: LoggerPluginConfig): HttixPlugin;
30
+
31
+ /**
32
+ * httix — Cache plugin
33
+ *
34
+ * LRU response cache with configurable TTL, size, stale-while-revalidate,
35
+ * and per-method caching control.
36
+ */
37
+
38
+ interface CachePluginConfig {
39
+ /** Maximum cache entries (default: 100) */
40
+ maxSize?: number;
41
+ /** TTL in ms (default: 300000 = 5 minutes) */
42
+ ttl?: number;
43
+ /** Whether to enable stale-while-revalidate (default: false) */
44
+ staleWhileRevalidate?: boolean;
45
+ /** SWR window in ms (default: 60000 = 1 minute) */
46
+ swrWindow?: number;
47
+ /** Custom cache key function */
48
+ generateKey?: (config: HttixRequestConfig) => string;
49
+ /** Which methods to cache (default: ['GET']) */
50
+ methods?: string[];
51
+ /** Whether to respect Cache-Control headers (default: true) */
52
+ respectCacheControl?: boolean;
53
+ }
54
+ interface CacheEntry<T = unknown> {
55
+ data: T;
56
+ status: number;
57
+ statusText: string;
58
+ headers: Headers;
59
+ timing: number;
60
+ timestamp: number;
61
+ config: HttixRequestConfig;
62
+ raw: Response;
63
+ }
64
+ declare class LRUCache<T = unknown> {
65
+ private cache;
66
+ private maxSize;
67
+ private ttl;
68
+ constructor(maxSize?: number, ttl?: number);
69
+ get(key: string): CacheEntry<T> | undefined;
70
+ /**
71
+ * Retrieve an entry even if it has expired (TTL exceeded).
72
+ * Returns undefined only when the key does not exist at all.
73
+ */
74
+ getAllowingStale(key: string): CacheEntry<T> | undefined;
75
+ set(key: string, entry: CacheEntry<T>): void;
76
+ has(key: string): boolean;
77
+ delete(key: string): boolean;
78
+ clear(): void;
79
+ get size(): number;
80
+ keys(): string[];
81
+ }
82
+ declare function cachePlugin(config?: CachePluginConfig): HttixPlugin & {
83
+ cache: LRUCache;
84
+ invalidate: (key?: string) => void;
85
+ invalidatePattern: (pattern: RegExp) => void;
86
+ clear: () => void;
87
+ getStats: () => {
88
+ size: number;
89
+ maxSize: number;
90
+ ttl: number;
91
+ };
92
+ };
93
+
94
+ /**
95
+ * httix — Mock plugin
96
+ *
97
+ * Replaces the global fetch with an in-memory mock adapter so tests can
98
+ * define request handlers and verify request history without hitting real
99
+ * endpoints.
100
+ */
101
+
102
+ interface MockHistoryEntry {
103
+ method: string;
104
+ url: string;
105
+ body?: unknown;
106
+ headers?: Record<string, string>;
107
+ config: HttixRequestConfig;
108
+ }
109
+ declare class MockAdapter {
110
+ private handlers;
111
+ private history;
112
+ private originalFetch;
113
+ private isActive;
114
+ /** Activate the mock — replace global fetch. */
115
+ activate(_client: HttixClient): void;
116
+ /** Deactivate — restore the original fetch. */
117
+ deactivate(): void;
118
+ /** Internal mock fetch implementation. */
119
+ private mockFetch;
120
+ onGet(url: string | RegExp): {
121
+ reply: (status: number, data: unknown, headers?: Record<string, string>) => MockAdapter;
122
+ };
123
+ onPost(url: string | RegExp): {
124
+ reply: (status: number, data: unknown, headers?: Record<string, string>) => MockAdapter;
125
+ };
126
+ onPut(url: string | RegExp): {
127
+ reply: (status: number, data: unknown, headers?: Record<string, string>) => MockAdapter;
128
+ };
129
+ onPatch(url: string | RegExp): {
130
+ reply: (status: number, data: unknown, headers?: Record<string, string>) => MockAdapter;
131
+ };
132
+ onDelete(url: string | RegExp): {
133
+ reply: (status: number, data: unknown, headers?: Record<string, string>) => MockAdapter;
134
+ };
135
+ private on;
136
+ /** Access recorded request history. */
137
+ getHistory(): Record<string, MockHistoryEntry[]>;
138
+ /** Clear all handlers and history (adapter stays active). */
139
+ reset(): void;
140
+ /** Fully deactivate and reset. */
141
+ restore(): void;
142
+ }
143
+ declare function mockPlugin(): HttixPlugin & {
144
+ adapter: MockAdapter;
145
+ onGet: MockAdapter['onGet'];
146
+ onPost: MockAdapter['onPost'];
147
+ onPut: MockAdapter['onPut'];
148
+ onPatch: MockAdapter['onPatch'];
149
+ onDelete: MockAdapter['onDelete'];
150
+ getHistory: () => Record<string, MockHistoryEntry[]>;
151
+ restore: () => void;
152
+ };
153
+
154
+ export { type CachePluginConfig, LRUCache, type LogLevel, type LoggerPluginConfig, MockAdapter, type MockHistoryEntry, cachePlugin, loggerPlugin, mockPlugin };
@@ -0,0 +1,340 @@
1
+ /**
2
+ * httix — Error class hierarchy
3
+ */
4
+
5
+ /**
6
+ * Base error class for all httix errors.
7
+ */
8
+ declare class HttixError extends Error {
9
+ readonly name: string;
10
+ readonly config?: HttixRequestConfig;
11
+ readonly cause?: Error;
12
+ constructor(message: string, options?: HttixErrorOptions);
13
+ }
14
+ /**
15
+ * Error thrown when a network-level request failure occurs
16
+ * (e.g., DNS failure, connection refused, CORS error).
17
+ */
18
+ declare class HttixRequestError extends HttixError {
19
+ readonly name: string;
20
+ constructor(message: string, options?: HttixErrorOptions);
21
+ }
22
+ /**
23
+ * Error thrown when the server responds with a 4xx or 5xx status code.
24
+ */
25
+ declare class HttixResponseError extends HttixError {
26
+ readonly name: string;
27
+ readonly status: number;
28
+ readonly statusText: string;
29
+ readonly data: unknown;
30
+ readonly headers?: Headers;
31
+ readonly config?: HttixRequestConfig;
32
+ constructor(status: number, statusText: string, data: unknown, headers?: Headers, config?: HttixRequestConfig);
33
+ }
34
+ /**
35
+ * Error thrown when a request exceeds its configured timeout.
36
+ */
37
+ declare class HttixTimeoutError extends HttixError {
38
+ readonly name: string;
39
+ readonly timeout: number;
40
+ constructor(timeout: number, config?: HttixRequestConfig);
41
+ }
42
+ /**
43
+ * Error thrown when a request is cancelled via AbortController.
44
+ */
45
+ declare class HttixAbortError extends HttixError {
46
+ readonly name: string;
47
+ readonly reason: string;
48
+ constructor(reason?: string, config?: HttixRequestConfig);
49
+ }
50
+ /**
51
+ * Error thrown when all retry attempts have been exhausted.
52
+ */
53
+ declare class HttixRetryError extends HttixError {
54
+ readonly name: string;
55
+ readonly attempts: number;
56
+ readonly lastError: HttixError;
57
+ constructor(attempts: number, lastError: HttixError, config?: HttixRequestConfig);
58
+ }
59
+
60
+ /**
61
+ * httix — Core TypeScript types and interfaces
62
+ */
63
+
64
+ /** Supported HTTP methods */
65
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
66
+ /** Body types that can be sent in a request */
67
+ type RequestBody = string | number | boolean | null | Record<string, unknown> | unknown[] | FormData | URLSearchParams | Blob | ArrayBuffer | ReadableStream<Uint8Array> | undefined;
68
+ /** Query parameter value types */
69
+ type QueryParamValue = string | number | boolean | null | undefined;
70
+ /** Query parameters object */
71
+ type QueryParams = Record<string, QueryParamValue | QueryParamValue[]>;
72
+ /** Path parameters for URL interpolation */
73
+ type PathParams = Record<string, string | number>;
74
+ /** Headers representation */
75
+ type HttixHeaders = Record<string, string> | Headers;
76
+ /** Backoff strategy for retry */
77
+ type BackoffStrategy = 'fixed' | 'linear' | 'exponential';
78
+ /** Rate limit configuration */
79
+ interface RateLimitConfig {
80
+ /** Maximum number of requests per interval */
81
+ maxRequests: number;
82
+ /** Interval in milliseconds */
83
+ interval: number;
84
+ }
85
+ /** Dedup configuration */
86
+ interface DedupConfig {
87
+ /** Enable request deduplication */
88
+ enabled: boolean;
89
+ /** Custom key generation function */
90
+ generateKey?: (config: HttixRequestConfig) => string;
91
+ /** TTL for dedup cache in ms (default: 0 = only dedup in-flight) */
92
+ ttl?: number;
93
+ }
94
+ /** Retry configuration */
95
+ interface RetryConfig {
96
+ /** Maximum number of retry attempts (default: 3) */
97
+ attempts?: number;
98
+ /** Backoff strategy (default: 'exponential') */
99
+ backoff?: BackoffStrategy;
100
+ /** Base delay in ms (default: 1000) */
101
+ baseDelay?: number;
102
+ /** Maximum delay in ms (default: 30000) */
103
+ maxDelay?: number;
104
+ /** Add jitter to delay (default: true) */
105
+ jitter?: boolean;
106
+ /** HTTP status codes to retry on (default: [408, 429, 500, 502, 503, 504]) */
107
+ retryOn?: number[];
108
+ /** Whether to retry on network errors (default: true) */
109
+ retryOnNetworkError?: boolean;
110
+ /** Custom retry condition function */
111
+ retryCondition?: (error: HttixError) => boolean;
112
+ /** Whether to retry on POST/PUT/PATCH (default: false) */
113
+ retryOnSafeMethodsOnly?: boolean;
114
+ /** Callback called before each retry */
115
+ onRetry?: (attempt: number, error: HttixError, delay: number) => void;
116
+ }
117
+ /** Authentication configuration */
118
+ type AuthConfig = BearerAuthConfig | BasicAuthConfig | ApiKeyAuthConfig;
119
+ interface BearerAuthConfig {
120
+ type: 'bearer';
121
+ /** Static token or a function that returns a token */
122
+ token: string | (() => string | Promise<string>);
123
+ /** Function to refresh the token when a 401 is received */
124
+ refreshToken?: () => Promise<string>;
125
+ /** Callback to store a refreshed token */
126
+ onTokenRefresh?: (token: string) => void;
127
+ }
128
+ interface BasicAuthConfig {
129
+ type: 'basic';
130
+ username: string;
131
+ password: string;
132
+ }
133
+ interface ApiKeyAuthConfig {
134
+ type: 'apiKey';
135
+ /** Header name (e.g., "X-API-Key") */
136
+ key: string;
137
+ /** API key value */
138
+ value: string | (() => string | Promise<string>);
139
+ /** Where to place the API key */
140
+ in: 'header' | 'query';
141
+ }
142
+ /** Pagination style */
143
+ type PaginationStyle = 'offset' | 'cursor' | 'link';
144
+ /** Pagination configuration */
145
+ interface PaginationConfig<T = unknown> {
146
+ /** Pagination style */
147
+ style: PaginationStyle;
148
+ /** Number of items per page */
149
+ pageSize?: number;
150
+ /** Maximum number of pages to fetch (default: Infinity) */
151
+ maxPages?: number;
152
+ /** For offset style: query param names for offset and limit */
153
+ offsetParam?: string;
154
+ /** For offset style: query param name for limit */
155
+ limitParam?: string;
156
+ /** For cursor style: query param name for cursor */
157
+ cursorParam?: string;
158
+ /** For cursor style: extractor for next cursor from response */
159
+ cursorExtractor?: (data: T) => string | null | undefined;
160
+ /** For link style: extractor for next URL from Link header */
161
+ linkExtractor?: (headers: Headers) => string | null | undefined;
162
+ /** Response wrapper — extract the array from the response data */
163
+ dataExtractor?: (data: T) => T[];
164
+ /** Stop condition */
165
+ stopCondition?: (data: T) => boolean;
166
+ }
167
+ /** Download progress info */
168
+ interface DownloadProgress {
169
+ loaded: number;
170
+ total?: number;
171
+ percent: number;
172
+ }
173
+ /** SSE event */
174
+ interface SSEEvent {
175
+ type: string;
176
+ data: string;
177
+ id?: string;
178
+ retry?: number;
179
+ }
180
+ /** Stream configuration */
181
+ interface StreamConfig {
182
+ /** SSE parser */
183
+ sse?: boolean;
184
+ /** NDJSON parser */
185
+ ndjson?: boolean;
186
+ /** Called for each chunk received */
187
+ onChunk?: (chunk: Uint8Array, index: number) => void;
188
+ }
189
+ /** Middleware context */
190
+ interface MiddlewareContext<Req = HttixRequestConfig, Res = HttixResponse<unknown>> {
191
+ request: Req;
192
+ response?: Res;
193
+ }
194
+ /** Middleware function */
195
+ type MiddlewareFn<T = unknown, Req = HttixRequestConfig, Res = HttixResponse<T>> = (ctx: MiddlewareContext<Req, Res>, next: () => Promise<void>) => Promise<void>;
196
+ /** Interceptor functions */
197
+ type RequestInterceptor = (config: HttixRequestConfig) => HttixRequestConfig | Promise<HttixRequestConfig>;
198
+ type RequestErrorInterceptor = (error: HttixError) => HttixRequestConfig | Promise<HttixRequestConfig> | void;
199
+ type ResponseInterceptor<T = unknown> = (response: HttixResponse<T>) => HttixResponse<T> | Promise<HttixResponse<T>>;
200
+ type ResponseErrorInterceptor = (error: HttixError) => HttixResponse<unknown> | Promise<HttixResponse<unknown>> | void;
201
+ /** Interceptor handler with id */
202
+ interface InterceptorHandler<F, E> {
203
+ fulfilled: F;
204
+ rejected?: E;
205
+ }
206
+ /** Interceptor manager */
207
+ interface InterceptorManager<F, E> {
208
+ handlers: InterceptorHandler<F, E>[];
209
+ use(fulfilled: F, rejected?: E): number;
210
+ eject(id: number): void;
211
+ clear(): void;
212
+ }
213
+ /** Full client configuration */
214
+ interface HttixConfig extends HttixRequestConfig {
215
+ /** Enable request deduplication (default: false) */
216
+ dedup?: boolean | DedupConfig;
217
+ /** Rate limiting configuration */
218
+ rateLimit?: RateLimitConfig;
219
+ /** Authentication configuration */
220
+ auth?: AuthConfig;
221
+ /** Middleware functions */
222
+ middleware?: MiddlewareFn[];
223
+ }
224
+ /** Per-request configuration */
225
+ interface HttixRequestConfig {
226
+ /** Request URL (relative or absolute) */
227
+ url: string;
228
+ /** HTTP method (default: 'GET') */
229
+ method?: HttpMethod;
230
+ /** Base URL for this request */
231
+ baseURL?: string;
232
+ /** Request headers */
233
+ headers?: HttixHeaders;
234
+ /** Request body */
235
+ body?: RequestBody;
236
+ /** Query parameters */
237
+ query?: QueryParams;
238
+ /** Path parameters for URL interpolation */
239
+ params?: PathParams;
240
+ /** Request timeout in ms (0 = no timeout) */
241
+ timeout?: number;
242
+ /** AbortSignal for cancellation */
243
+ signal?: AbortSignal;
244
+ /** Retry configuration for this request */
245
+ retry?: RetryConfig | false;
246
+ /** Response type override */
247
+ responseType?: 'json' | 'text' | 'blob' | 'arrayBuffer';
248
+ /** Custom response type parser */
249
+ parseResponse?: (response: Response) => Promise<unknown>;
250
+ /** Download progress callback */
251
+ onDownloadProgress?: (progress: DownloadProgress) => void;
252
+ /** Stream configuration */
253
+ stream?: StreamConfig;
254
+ /** Custom request credentials mode */
255
+ credentials?: RequestCredentials;
256
+ /** Custom request mode */
257
+ mode?: RequestMode;
258
+ /** Custom cache mode */
259
+ cache?: RequestCache;
260
+ /** Custom redirect mode */
261
+ redirect?: RequestRedirect;
262
+ /** Custom referrer policy */
263
+ referrerPolicy?: ReferrerPolicy;
264
+ /** Request ID for tracing */
265
+ requestId?: string;
266
+ /** Whether to throw on non-2xx status (default: true) */
267
+ throwOnError?: boolean;
268
+ }
269
+ /** Httix response wrapper */
270
+ interface HttixResponse<T = unknown> {
271
+ /** Parsed response body */
272
+ data: T;
273
+ /** HTTP status code */
274
+ status: number;
275
+ /** HTTP status text */
276
+ statusText: string;
277
+ /** Response headers */
278
+ headers: Headers;
279
+ /** Whether the status is 2xx */
280
+ ok: boolean;
281
+ /** Original Fetch Response object */
282
+ raw: Response;
283
+ /** Request duration in ms */
284
+ timing: number;
285
+ /** The request config that produced this response */
286
+ config: HttixRequestConfig;
287
+ }
288
+ /** Base error class for all httix errors */
289
+ interface HttixErrorOptions {
290
+ message: string;
291
+ config?: HttixRequestConfig;
292
+ cause?: Error;
293
+ }
294
+ /** Plugin interface */
295
+ interface HttixPlugin {
296
+ /** Plugin name */
297
+ name: string;
298
+ /** Install hook — called when plugin is registered */
299
+ install: (client: HttixClient) => void;
300
+ /** Cleanup hook — called when plugin is removed */
301
+ cleanup?: () => void;
302
+ }
303
+ /** HttixClient interface */
304
+ interface HttixClient {
305
+ /** Default configuration */
306
+ defaults: HttixConfig;
307
+ /** Request interceptors */
308
+ interceptors: {
309
+ request: InterceptorManager<RequestInterceptor, RequestErrorInterceptor>;
310
+ response: InterceptorManager<ResponseInterceptor<unknown>, ResponseErrorInterceptor>;
311
+ };
312
+ /** HTTP methods */
313
+ get<T = unknown>(url: string, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<T>>;
314
+ post<T = unknown>(url: string, body?: RequestBody, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<T>>;
315
+ put<T = unknown>(url: string, body?: RequestBody, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<T>>;
316
+ patch<T = unknown>(url: string, body?: RequestBody, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<T>>;
317
+ delete<T = unknown>(url: string, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<T>>;
318
+ head(url: string, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<void>>;
319
+ options(url: string, config?: Partial<HttixRequestConfig>): Promise<HttixResponse<void>>;
320
+ request<T = unknown>(config: HttixRequestConfig): Promise<HttixResponse<T>>;
321
+ /** Stream support */
322
+ stream: {
323
+ sse(url: string, config?: Partial<HttixRequestConfig>): AsyncIterable<SSEEvent>;
324
+ ndjson<T = unknown>(url: string, config?: Partial<HttixRequestConfig>): AsyncIterable<T>;
325
+ };
326
+ /** Pagination */
327
+ paginate<T = unknown>(url: string, config?: Partial<HttixRequestConfig> & {
328
+ pagination?: PaginationConfig<T>;
329
+ }): AsyncIterable<T[]>;
330
+ /** Middleware registration */
331
+ use<T = unknown>(middleware: MiddlewareFn<T>): void;
332
+ /** Clone client with overrides */
333
+ create(overrides?: Partial<HttixConfig>): HttixClient;
334
+ /** Cancel all pending requests */
335
+ cancelAll(reason?: string): void;
336
+ /** Check if error is a cancellation error */
337
+ isCancel(error: unknown): error is HttixAbortError;
338
+ }
339
+
340
+ export { type AuthConfig as A, type BearerAuthConfig as B, type RateLimitConfig as C, type DownloadProgress as D, type StreamConfig as E, type HttixClient as H, type InterceptorManager as I, type MiddlewareFn as M, type PaginationConfig as P, type QueryParamValue as Q, type RequestInterceptor as R, type SSEEvent as S, type InterceptorHandler as a, type HttixConfig as b, type RequestErrorInterceptor as c, type ResponseInterceptor as d, type ResponseErrorInterceptor as e, type HttixRequestConfig as f, type HttixResponse as g, type RequestBody as h, HttixAbortError as i, type RetryConfig as j, type MiddlewareContext as k, type ApiKeyAuthConfig as l, type BackoffStrategy as m, type BasicAuthConfig as n, type DedupConfig as o, HttixError as p, type HttixHeaders as q, type HttixPlugin as r, HttixRequestError as s, HttixResponseError as t, HttixRetryError as u, HttixTimeoutError as v, type HttpMethod as w, type PaginationStyle as x, type PathParams as y, type QueryParams as z };