@igniter-js/caller 0.1.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,738 @@
1
+ import { StandardSchemaV1, IgniterLogger, IgniterError } from '@igniter-js/core';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Supported HTTP methods for `IgniterCaller` requests.
6
+ *
7
+ * This type is designed to remain stable when extracted to `@igniter-js/caller`.
8
+ */
9
+ type IgniterCallerHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
10
+
11
+ /**
12
+ * Base configuration options for HTTP requests.
13
+ */
14
+ interface IgniterCallerBaseRequestOptions {
15
+ /** Base URL for all requests (e.g. `https://api.example.com`). */
16
+ baseURL?: string;
17
+ /** Default headers merged into each request. */
18
+ headers?: Record<string, string>;
19
+ /** Request timeout in milliseconds (default: 30000). */
20
+ timeout?: number;
21
+ }
22
+ /**
23
+ * Complete request configuration extending base options.
24
+ */
25
+ interface IgniterCallerRequestOptions<TBody = unknown> extends IgniterCallerBaseRequestOptions {
26
+ method: IgniterCallerHttpMethod;
27
+ /** Endpoint URL path. If absolute, `baseURL` is ignored. */
28
+ url: string;
29
+ body?: TBody;
30
+ params?: Record<string, string | number | boolean>;
31
+ responseSchema?: z.ZodSchema<any>;
32
+ cache?: RequestCache;
33
+ }
34
+
35
+ /**
36
+ * Response object containing either successful data or an error.
37
+ */
38
+ interface IgniterCallerApiResponse<T> {
39
+ data?: T;
40
+ error?: Error;
41
+ }
42
+ /**
43
+ * Response object for file downloads.
44
+ */
45
+ interface IgniterCallerFileResponse {
46
+ file: File | null;
47
+ error: Error | null;
48
+ }
49
+
50
+ /**
51
+ * Function that can modify request configuration before execution.
52
+ */
53
+ type IgniterCallerRequestInterceptor = (config: IgniterCallerRequestOptions) => Promise<IgniterCallerRequestOptions> | IgniterCallerRequestOptions;
54
+ /**
55
+ * Function that can transform responses after execution.
56
+ */
57
+ type IgniterCallerResponseInterceptor = <T>(response: IgniterCallerApiResponse<T>) => Promise<IgniterCallerApiResponse<T>> | IgniterCallerApiResponse<T>;
58
+
59
+ /**
60
+ * HTTP methods supported for schema mapping.
61
+ */
62
+ type IgniterCallerSchemaMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
63
+ /**
64
+ * Schema definition for a single endpoint.
65
+ *
66
+ * Maps status codes to response schemas with optional request schema.
67
+ */
68
+ type IgniterCallerEndpointSchema<TRequest extends StandardSchemaV1 = any, TResponses extends Record<number, StandardSchemaV1> = Record<number, StandardSchemaV1>> = {
69
+ /** Request body schema (optional) */
70
+ request?: TRequest;
71
+ /** Response schemas by status code */
72
+ responses: TResponses;
73
+ };
74
+ /**
75
+ * Schema map for multiple endpoints.
76
+ *
77
+ * Structure: { [path]: { [method]: EndpointSchema } }
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const schemas = {
82
+ * '/users': {
83
+ * GET: {
84
+ * responses: {
85
+ * 200: z.array(UserSchema),
86
+ * 401: z.object({ error: z.string() }),
87
+ * },
88
+ * },
89
+ * POST: {
90
+ * request: CreateUserSchema,
91
+ * responses: {
92
+ * 201: UserSchema,
93
+ * 400: z.object({ errors: z.array(z.string()) }),
94
+ * },
95
+ * },
96
+ * },
97
+ * '/users/:id': {
98
+ * GET: {
99
+ * responses: {
100
+ * 200: UserSchema,
101
+ * 404: z.object({ error: z.string() }),
102
+ * },
103
+ * },
104
+ * },
105
+ * }
106
+ * ```
107
+ */
108
+ type IgniterCallerSchemaMap = Record<string, Partial<Record<IgniterCallerSchemaMethod, IgniterCallerEndpointSchema<any, any>>>>;
109
+ /**
110
+ * Extract path parameters from a URL pattern.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * type Params = ExtractPathParams<'/users/:id/posts/:postId'>
115
+ * // { id: string; postId: string }
116
+ * ```
117
+ */
118
+ type ExtractPathParams<T extends string> = T extends `${infer _Start}:${infer Param}/${infer Rest}` ? {
119
+ [K in Param | keyof ExtractPathParams<`/${Rest}`>]: string;
120
+ } : T extends `${infer _Start}:${infer Param}` ? {
121
+ [K in Param]: string;
122
+ } : Record<never, never>;
123
+ /**
124
+ * Infer request type from endpoint schema.
125
+ */
126
+ type InferRequestType<T> = T extends IgniterCallerEndpointSchema<infer R, any> ? R extends StandardSchemaV1 ? StandardSchemaV1.InferInput<R> : never : never;
127
+ /**
128
+ * Infer response type by status code from endpoint schema.
129
+ */
130
+ type InferResponseType<T, Status extends number> = T extends IgniterCallerEndpointSchema<any, infer Responses> ? Status extends keyof Responses ? Responses[Status] extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Responses[Status]> : never : never : never;
131
+ /**
132
+ * Infer all possible response types (union) from endpoint schema.
133
+ */
134
+ type InferAllResponseTypes<T> = T extends IgniterCallerEndpointSchema<any, infer Responses> ? Responses extends Record<number, StandardSchemaV1> ? {
135
+ [K in keyof Responses]: Responses[K] extends StandardSchemaV1 ? {
136
+ status: K;
137
+ data: StandardSchemaV1.InferOutput<Responses[K]>;
138
+ } : never;
139
+ }[keyof Responses] : never : never;
140
+ /**
141
+ * Options for schema validation behavior.
142
+ */
143
+ interface IgniterCallerSchemaValidationOptions {
144
+ /**
145
+ * Validation mode:
146
+ * - 'strict': Throw error on validation failure (default)
147
+ * - 'soft': Log error but return raw data
148
+ * - 'off': Skip validation entirely
149
+ */
150
+ mode?: 'strict' | 'soft' | 'off';
151
+ /**
152
+ * Custom error handler for validation failures.
153
+ */
154
+ onValidationError?: (error: any, context: {
155
+ url: string;
156
+ method: string;
157
+ statusCode: number;
158
+ }) => void;
159
+ }
160
+
161
+ /**
162
+ * Store adapter interface compatible with Igniter.js Store.
163
+ *
164
+ * This allows IgniterCaller to use any store implementation (Redis, in-memory, etc.)
165
+ * for persistent caching across requests and deployments.
166
+ */
167
+ interface IgniterCallerStoreAdapter<TClient = any> {
168
+ /** The underlying client instance (e.g., Redis client). */
169
+ readonly client: TClient;
170
+ /**
171
+ * Retrieves a value from the store by its key.
172
+ * @param key The key to retrieve.
173
+ * @returns The value if found (auto-deserialized), otherwise null.
174
+ */
175
+ get<T = any>(key: string): Promise<T | null>;
176
+ /**
177
+ * Stores a value in the store.
178
+ * @param key The key to store the value under.
179
+ * @param value The value to store (will be auto-serialized).
180
+ * @param options Configuration options, such as TTL.
181
+ */
182
+ set(key: string, value: any, options?: {
183
+ ttl?: number;
184
+ [key: string]: any;
185
+ }): Promise<void>;
186
+ /**
187
+ * Deletes a key from the store.
188
+ * @param key The key to delete.
189
+ */
190
+ delete(key: string): Promise<void>;
191
+ /**
192
+ * Checks if a key exists in the store.
193
+ * @param key The key to check.
194
+ * @returns `true` if the key exists, otherwise `false`.
195
+ */
196
+ has(key: string): Promise<boolean>;
197
+ }
198
+ /**
199
+ * Configuration options for store-based caching.
200
+ */
201
+ interface IgniterCallerStoreOptions {
202
+ /** Default TTL in seconds for cached entries (default: 3600 = 1 hour). */
203
+ ttl?: number;
204
+ /** Prefix for all cache keys (default: 'igniter:caller:'). */
205
+ keyPrefix?: string;
206
+ /** Whether to fallback to fetch cache when store is unavailable (default: true). */
207
+ fallbackToFetch?: boolean;
208
+ }
209
+
210
+ type IgniterCallerBuilderState<TSchemas extends IgniterCallerSchemaMap = any> = {
211
+ baseURL?: string;
212
+ headers?: Record<string, string>;
213
+ cookies?: Record<string, string>;
214
+ logger?: IgniterLogger;
215
+ requestInterceptors?: IgniterCallerRequestInterceptor[];
216
+ responseInterceptors?: IgniterCallerResponseInterceptor[];
217
+ store?: IgniterCallerStoreAdapter;
218
+ storeOptions?: IgniterCallerStoreOptions;
219
+ schemas?: TSchemas;
220
+ schemaValidation?: IgniterCallerSchemaValidationOptions;
221
+ };
222
+ type IgniterCallerBuilderFactory<TCaller, TSchemas extends IgniterCallerSchemaMap = any> = (state: IgniterCallerBuilderState<TSchemas>) => TCaller;
223
+ /**
224
+ * Builder used by developers to initialize the `IgniterCaller` client.
225
+ *
226
+ * This API is designed to remain stable when extracted to `@igniter-js/caller`.
227
+ */
228
+ declare class IgniterCallerBuilder<TCaller = unknown, TSchemas extends IgniterCallerSchemaMap = any> {
229
+ private readonly state;
230
+ private readonly factory;
231
+ private constructor();
232
+ /**
233
+ * Creates a new builder instance.
234
+ */
235
+ static create<TCaller, TSchemas extends IgniterCallerSchemaMap = any>(factory: IgniterCallerBuilderFactory<TCaller, TSchemas>): IgniterCallerBuilder<TCaller, TSchemas>;
236
+ /** Sets the base URL for all requests. */
237
+ withBaseUrl(baseURL: string): IgniterCallerBuilder<TCaller, TSchemas>;
238
+ /** Merges default headers for all requests. */
239
+ withHeaders(headers: Record<string, string>): IgniterCallerBuilder<TCaller>;
240
+ /** Sets default cookies (sent as the `Cookie` header). */
241
+ withCookies(cookies: Record<string, string>): IgniterCallerBuilder<TCaller>;
242
+ /** Attaches a logger instance. */
243
+ withLogger(logger: IgniterLogger): IgniterCallerBuilder<TCaller, TSchemas>;
244
+ /** Adds a request interceptor that runs before each request. */
245
+ withRequestInterceptor(interceptor: IgniterCallerRequestInterceptor): IgniterCallerBuilder<TCaller, TSchemas>;
246
+ /** Adds a response interceptor that runs after each request. */
247
+ withResponseInterceptor(interceptor: IgniterCallerResponseInterceptor): IgniterCallerBuilder<TCaller, TSchemas>;
248
+ /**
249
+ * Configures a persistent store adapter for caching.
250
+ *
251
+ * When configured, cache operations will use the store (e.g., Redis)
252
+ * instead of in-memory cache, enabling persistent cache across deployments.
253
+ */
254
+ withStore(store: IgniterCallerStoreAdapter, options?: IgniterCallerStoreOptions): IgniterCallerBuilder<TCaller, TSchemas>;
255
+ /**
256
+ * Configures schema-based type safety and validation.
257
+ *
258
+ * Enables automatic type inference for requests/responses based on
259
+ * route and method, with optional runtime validation via Zod.
260
+ *
261
+ * @example
262
+ * ```ts
263
+ * const api = IgniterCaller.create()
264
+ * .withSchemas({
265
+ * '/users': {
266
+ * GET: {
267
+ * responses: {
268
+ * 200: z.array(UserSchema),
269
+ * 401: ErrorSchema,
270
+ * },
271
+ * },
272
+ * POST: {
273
+ * request: CreateUserSchema,
274
+ * responses: {
275
+ * 201: UserSchema,
276
+ * 400: ValidationErrorSchema,
277
+ * },
278
+ * },
279
+ * },
280
+ * })
281
+ * .build()
282
+ * ```
283
+ */
284
+ withSchemas<TNewSchemas extends IgniterCallerSchemaMap>(schemas: TNewSchemas, validation?: IgniterCallerSchemaValidationOptions): IgniterCallerBuilder<TCaller, TNewSchemas>;
285
+ /**
286
+ * Builds the `IgniterCaller` instance.
287
+ */
288
+ build(): TCaller;
289
+ }
290
+
291
+ /**
292
+ * Retry configuration for failed requests.
293
+ */
294
+ interface IgniterCallerRetryOptions {
295
+ /** Maximum number of retry attempts. */
296
+ maxAttempts: number;
297
+ /** Backoff strategy between retries. */
298
+ backoff?: 'linear' | 'exponential';
299
+ /** Base delay in milliseconds (default: 1000). */
300
+ baseDelay?: number;
301
+ /** HTTP status codes that should trigger a retry (default: [408, 429, 500, 502, 503, 504]). */
302
+ retryOnStatus?: number[];
303
+ }
304
+
305
+ /**
306
+ * Fluent request builder for `IgniterCaller`.
307
+ */
308
+ declare class IgniterCallerRequestBuilder {
309
+ private options;
310
+ private logger?;
311
+ private retryOptions?;
312
+ private fallbackFn?;
313
+ private cacheKey?;
314
+ private staleTime?;
315
+ private requestInterceptors?;
316
+ private responseInterceptors?;
317
+ private eventEmitter?;
318
+ private schemas?;
319
+ private schemaValidation?;
320
+ constructor(params: {
321
+ baseURL?: string;
322
+ defaultHeaders?: Record<string, string>;
323
+ defaultCookies?: Record<string, string>;
324
+ logger?: IgniterLogger;
325
+ requestInterceptors?: IgniterCallerRequestInterceptor[];
326
+ responseInterceptors?: IgniterCallerResponseInterceptor[];
327
+ eventEmitter?: (url: string, method: string, result: any) => Promise<void>;
328
+ schemas?: IgniterCallerSchemaMap;
329
+ schemaValidation?: IgniterCallerSchemaValidationOptions;
330
+ });
331
+ /**
332
+ * Overrides the logger for this request chain.
333
+ */
334
+ withLogger(logger: IgniterLogger): this;
335
+ method(method: IgniterCallerHttpMethod): this;
336
+ url(url: string): this;
337
+ body<TBody>(body: TBody): this;
338
+ params(params: Record<string, string | number | boolean>): this;
339
+ headers(headers: Record<string, string>): this;
340
+ timeout(timeout: number): this;
341
+ cache(cache: RequestCache, key?: string): this;
342
+ /**
343
+ * Configures retry behavior for failed requests.
344
+ */
345
+ retry(maxAttempts: number, options?: Omit<IgniterCallerRetryOptions, 'maxAttempts'>): this;
346
+ /**
347
+ * Provides a fallback value if the request fails.
348
+ */
349
+ fallback<T>(fn: () => T): this;
350
+ /**
351
+ * Sets cache stale time in milliseconds.
352
+ */
353
+ stale(milliseconds: number): this;
354
+ responseType<T>(schema?: z.ZodSchema<T>): this;
355
+ /**
356
+ * Downloads a file via GET request.
357
+ */
358
+ getFile(url: string): {
359
+ execute: () => Promise<IgniterCallerFileResponse>;
360
+ };
361
+ execute<T = unknown>(): Promise<IgniterCallerApiResponse<T>>;
362
+ private executeWithRetry;
363
+ private executeSingleRequest;
364
+ private buildRequest;
365
+ /**
366
+ * Emits event for this response using injected emitter.
367
+ */
368
+ private emitEvent;
369
+ }
370
+
371
+ /**
372
+ * Callback function for event listeners.
373
+ */
374
+ type IgniterCallerEventCallback<T = any> = (result: IgniterCallerApiResponse<T>, context: {
375
+ url: string;
376
+ method: string;
377
+ timestamp: number;
378
+ }) => void | Promise<void>;
379
+ /**
380
+ * Pattern for matching URLs (string or RegExp).
381
+ */
382
+ type IgniterCallerUrlPattern = string | RegExp;
383
+
384
+ /**
385
+ * HTTP client runtime for Igniter.js.
386
+ *
387
+ * This module is intentionally structured to be extracted into a standalone package
388
+ * in the Igniter.js ecosystem as `@igniter-js/caller`.
389
+ */
390
+ declare class IgniterCaller {
391
+ /** Global event emitter for observing HTTP responses */
392
+ private static readonly events;
393
+ private baseURL?;
394
+ private headers?;
395
+ private cookies?;
396
+ private logger?;
397
+ private requestInterceptors?;
398
+ private responseInterceptors?;
399
+ private schemas?;
400
+ private schemaValidation?;
401
+ constructor(baseURL?: string, opts?: {
402
+ headers?: Record<string, string>;
403
+ cookies?: Record<string, string>;
404
+ logger?: IgniterLogger;
405
+ requestInterceptors?: IgniterCallerRequestInterceptor[];
406
+ responseInterceptors?: IgniterCallerResponseInterceptor[];
407
+ schemas?: IgniterCallerSchemaMap;
408
+ schemaValidation?: IgniterCallerSchemaValidationOptions;
409
+ });
410
+ /**
411
+ * Canonical initialization entrypoint.
412
+ *
413
+ * This is designed to remain stable when extracted to `@igniter-js/caller`.
414
+ */
415
+ static create(): IgniterCallerBuilder<IgniterCaller>;
416
+ /**
417
+ * Returns a new client with the same config and a new logger.
418
+ */
419
+ withLogger(logger: IgniterLogger): IgniterCaller;
420
+ setBaseURL(baseURL: string): this;
421
+ setHeaders(headers: Record<string, string>): this;
422
+ setCookies(cookies: Record<string, string>): this;
423
+ get(): IgniterCallerRequestBuilder;
424
+ post(): IgniterCallerRequestBuilder;
425
+ put(): IgniterCallerRequestBuilder;
426
+ patch(): IgniterCallerRequestBuilder;
427
+ delete(): IgniterCallerRequestBuilder;
428
+ request(): IgniterCallerRequestBuilder;
429
+ /**
430
+ * Executes multiple requests in parallel and returns results as an array.
431
+ *
432
+ * This is useful for batching independent API calls.
433
+ */
434
+ static batch<T extends readonly Promise<IgniterCallerApiResponse<any>>[]>(requests: [...T]): Promise<{
435
+ [K in keyof T]: T[K] extends Promise<infer R> ? R : never;
436
+ }>;
437
+ /**
438
+ * Registers a global event listener for HTTP responses.
439
+ *
440
+ * This allows observing API responses across the application for:
441
+ * - Debugging and logging
442
+ * - Real-time monitoring
443
+ * - Cache invalidation triggers
444
+ * - Analytics and telemetry
445
+ *
446
+ * @param pattern URL string (exact match) or RegExp pattern
447
+ * @param callback Function to execute when a response matches
448
+ * @returns Cleanup function to remove the listener
449
+ *
450
+ * @example
451
+ * ```ts
452
+ * // Listen to all user endpoints
453
+ * const cleanup = IgniterCaller.on(/^\/users/, (result, context) => {
454
+ * console.log(`${context.method} ${context.url}`, result)
455
+ * })
456
+ *
457
+ * // Cleanup when done
458
+ * cleanup()
459
+ * ```
460
+ */
461
+ static on(pattern: IgniterCallerUrlPattern, callback: IgniterCallerEventCallback): () => void;
462
+ /**
463
+ * Removes event listeners for a pattern.
464
+ */
465
+ static off(pattern: IgniterCallerUrlPattern, callback?: IgniterCallerEventCallback): void;
466
+ /**
467
+ * Invalidates a specific cache entry.
468
+ *
469
+ * This is useful after mutations to ensure fresh data on next fetch.
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * // After creating a user
474
+ * await api.post().url('/users').body(newUser).execute()
475
+ * await IgniterCaller.invalidate('/users') // Clear users list cache
476
+ * ```
477
+ */
478
+ static invalidate(key: string): Promise<void>;
479
+ /**
480
+ * Invalidates all cache entries matching a pattern.
481
+ *
482
+ * @param pattern Glob pattern (e.g., '/users/*') or exact key
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * // Invalidate all user-related caches
487
+ * await IgniterCaller.invalidatePattern('/users/*')
488
+ * ```
489
+ */
490
+ static invalidatePattern(pattern: string): Promise<void>;
491
+ /**
492
+ * Emits an event to all registered listeners.
493
+ *
494
+ * @internal
495
+ */
496
+ static emitEvent(url: string, method: string, result: IgniterCallerApiResponse<any>): Promise<void>;
497
+ }
498
+
499
+ /**
500
+ * Event emitter for observing HTTP responses across the application.
501
+ *
502
+ * This allows developers to listen to API responses globally for:
503
+ * - Debugging and logging
504
+ * - Real-time monitoring
505
+ * - Cache invalidation triggers
506
+ * - Analytics and telemetry
507
+ */
508
+ declare class IgniterCallerEvents {
509
+ private listeners;
510
+ private patternListeners;
511
+ /**
512
+ * Registers a listener for a specific URL or pattern.
513
+ *
514
+ * @param pattern URL string (exact match) or RegExp pattern
515
+ * @param callback Function to execute when a response matches
516
+ * @returns Cleanup function to remove the listener
517
+ *
518
+ * @example
519
+ * ```ts
520
+ * // Listen to specific endpoint
521
+ * const cleanup = api.on('/users', (result) => {
522
+ * console.log('Users fetched:', result.data)
523
+ * })
524
+ *
525
+ * // Listen to pattern
526
+ * api.on(/^\/users\/\d+$/, (result) => {
527
+ * console.log('User detail fetched')
528
+ * })
529
+ *
530
+ * // Cleanup when done
531
+ * cleanup()
532
+ * ```
533
+ */
534
+ on(pattern: IgniterCallerUrlPattern, callback: IgniterCallerEventCallback): () => void;
535
+ /**
536
+ * Removes a specific listener or all listeners for a pattern.
537
+ */
538
+ off(pattern: IgniterCallerUrlPattern, callback?: IgniterCallerEventCallback): void;
539
+ /**
540
+ * Emits an event to all matching listeners.
541
+ *
542
+ * @internal
543
+ */
544
+ emit(url: string, method: string, result: any): Promise<void>;
545
+ /**
546
+ * Removes all listeners.
547
+ */
548
+ clear(): void;
549
+ }
550
+
551
+ type IgniterCallerErrorCode = 'IGNITER_CALLER_HTTP_ERROR' | 'IGNITER_CALLER_TIMEOUT' | 'IGNITER_CALLER_REQUEST_VALIDATION_FAILED' | 'IGNITER_CALLER_RESPONSE_VALIDATION_FAILED' | 'IGNITER_CALLER_UNKNOWN_ERROR';
552
+ type IgniterCallerOperation = 'execute' | 'download' | 'buildRequest' | 'parseResponse' | 'validateRequest' | 'validateResponse';
553
+ /**
554
+ * Payload used to create an {@link IgniterCallerError}.
555
+ */
556
+ type IgniterCallerErrorPayload = {
557
+ /** Machine-readable error code. */
558
+ code: IgniterCallerErrorCode;
559
+ /** Where the error happened. */
560
+ operation: IgniterCallerOperation;
561
+ /** Human-readable message. */
562
+ message: string;
563
+ /** Optional HTTP status code when surfacing errors through HTTP boundaries. */
564
+ statusCode?: number;
565
+ /** Optional HTTP status text (when available). */
566
+ statusText?: string;
567
+ /** Extra diagnostic details (e.g. response body or schema issues). */
568
+ details?: unknown;
569
+ /** Arbitrary metadata for debugging. */
570
+ metadata?: Record<string, unknown>;
571
+ /** Optional original cause. */
572
+ cause?: unknown;
573
+ /** Optional logger used by IgniterError. */
574
+ logger?: IgniterLogger;
575
+ };
576
+ /**
577
+ * Typed error for predictable failures in `IgniterCaller`.
578
+ *
579
+ * Designed to be extracted into `@igniter-js/caller`.
580
+ */
581
+ declare class IgniterCallerError extends IgniterError {
582
+ readonly code: IgniterCallerErrorCode;
583
+ readonly operation: IgniterCallerOperation;
584
+ readonly statusText?: string;
585
+ readonly cause?: unknown;
586
+ constructor(payload: IgniterCallerErrorPayload);
587
+ static is(error: unknown): error is IgniterCallerError;
588
+ }
589
+
590
+ declare class IgniterCallerBodyUtils {
591
+ /**
592
+ * Returns true when the request body should be passed to `fetch` as-is.
593
+ */
594
+ static isRawBody(body: unknown): boolean;
595
+ /**
596
+ * Removes Content-Type for FormData so fetch can set boundaries automatically.
597
+ */
598
+ static normalizeHeadersForBody(headers: Record<string, string> | undefined, body: unknown): Record<string, string> | undefined;
599
+ }
600
+
601
+ /**
602
+ * Cache interface for HTTP responses.
603
+ *
604
+ * Supports both in-memory caching and persistent store-based caching (Redis, etc).
605
+ */
606
+ declare class IgniterCallerCacheUtils {
607
+ private static cache;
608
+ private static store;
609
+ private static storeOptions;
610
+ /**
611
+ * Configures a persistent store adapter for caching.
612
+ *
613
+ * When configured, cache operations will use the store (e.g., Redis)
614
+ * instead of in-memory cache, enabling persistent cache across deployments.
615
+ */
616
+ static setStore(store: IgniterCallerStoreAdapter, options?: IgniterCallerStoreOptions): void;
617
+ /**
618
+ * Gets the configured store adapter.
619
+ */
620
+ static getStore(): IgniterCallerStoreAdapter | null;
621
+ /**
622
+ * Gets cached data if it exists and is not stale.
623
+ */
624
+ static get<T>(key: string, staleTime?: number): Promise<T | undefined>;
625
+ /**
626
+ * Stores data in cache with current timestamp.
627
+ */
628
+ static set(key: string, data: unknown, ttl?: number): Promise<void>;
629
+ /**
630
+ * Clears a specific cache entry.
631
+ */
632
+ static clear(key: string): Promise<void>;
633
+ /**
634
+ * Clears all cache entries matching a pattern.
635
+ *
636
+ * @param pattern Glob pattern (e.g., '/users/*') or exact key
637
+ */
638
+ static clearPattern(pattern: string): Promise<void>;
639
+ /**
640
+ * Clears all cache entries.
641
+ */
642
+ static clearAll(): Promise<void>;
643
+ /**
644
+ * Adds the configured prefix to a key.
645
+ */
646
+ private static getPrefixedKey;
647
+ /**
648
+ * Converts a glob pattern to a RegExp.
649
+ */
650
+ private static globToRegex;
651
+ }
652
+
653
+ /**
654
+ * Utilities for schema matching and validation.
655
+ *
656
+ * @internal
657
+ */
658
+ declare class IgniterCallerSchemaUtils {
659
+ /**
660
+ * Matches a URL path against schema map paths (supports path parameters).
661
+ *
662
+ * @example
663
+ * ```ts
664
+ * matchPath('/users/123', '/users/:id') // { matched: true, params: { id: '123' } }
665
+ * matchPath('/users', '/users/:id') // { matched: false }
666
+ * ```
667
+ */
668
+ static matchPath(actualPath: string, schemaPath: string): {
669
+ matched: boolean;
670
+ params?: Record<string, string>;
671
+ };
672
+ /**
673
+ * Finds the schema for a given path and method from the schema map.
674
+ */
675
+ static findSchema(schemaMap: IgniterCallerSchemaMap | undefined, path: string, method: string): {
676
+ schema: IgniterCallerEndpointSchema | undefined;
677
+ params: Record<string, string>;
678
+ };
679
+ /**
680
+ * Validates input using StandardSchemaV1.
681
+ *
682
+ * If the schema provides `~standard.validate`, it will be used.
683
+ * Otherwise, returns the input as-is.
684
+ */
685
+ private static validateWithStandardSchema;
686
+ /**
687
+ * Validates request body against schema.
688
+ *
689
+ * @returns Validated data or throws/logs error based on validation mode
690
+ */
691
+ static validateRequest<T>(data: unknown, schema: StandardSchemaV1 | undefined, options: IgniterCallerSchemaValidationOptions | undefined, context: {
692
+ url: string;
693
+ method: string;
694
+ }, logger?: IgniterLogger): Promise<T>;
695
+ /**
696
+ * Validates response data against schema.
697
+ *
698
+ * @returns Validated data or throws/logs error based on validation mode
699
+ */
700
+ static validateResponse<T>(data: unknown, schema: StandardSchemaV1 | undefined, statusCode: number, options: IgniterCallerSchemaValidationOptions | undefined, context: {
701
+ url: string;
702
+ method: string;
703
+ }, logger?: IgniterLogger): Promise<T>;
704
+ }
705
+
706
+ /**
707
+ * Testing utilities for `IgniterCaller`.
708
+ *
709
+ * Designed to simplify mocking HTTP responses in unit tests.
710
+ */
711
+ declare class IgniterCallerMock {
712
+ /**
713
+ * Creates a successful mock response.
714
+ */
715
+ static mockResponse<T>(data: T): IgniterCallerApiResponse<T>;
716
+ /**
717
+ * Creates an error mock response.
718
+ */
719
+ static mockError<T = never>(code: IgniterCallerErrorCode, message?: string): IgniterCallerApiResponse<T>;
720
+ /**
721
+ * Creates a successful file download mock.
722
+ */
723
+ static mockFile(filename: string, content: string | Blob): IgniterCallerFileResponse;
724
+ /**
725
+ * Creates a failed file download mock.
726
+ */
727
+ static mockFileError(message?: string): IgniterCallerFileResponse;
728
+ }
729
+
730
+ declare class IgniterCallerUrlUtils {
731
+ static buildUrl(params: {
732
+ url: string;
733
+ baseURL?: string;
734
+ query?: Record<string, string | number | boolean>;
735
+ }): string;
736
+ }
737
+
738
+ export { type ExtractPathParams, IgniterCaller, type IgniterCallerApiResponse, type IgniterCallerBaseRequestOptions, IgniterCallerBodyUtils, IgniterCallerBuilder, type IgniterCallerBuilderFactory, type IgniterCallerBuilderState, IgniterCallerCacheUtils, type IgniterCallerEndpointSchema, IgniterCallerError, type IgniterCallerErrorCode, type IgniterCallerErrorPayload, type IgniterCallerEventCallback, IgniterCallerEvents, type IgniterCallerFileResponse, type IgniterCallerHttpMethod, IgniterCallerMock, type IgniterCallerOperation, IgniterCallerRequestBuilder, type IgniterCallerRequestInterceptor, type IgniterCallerRequestOptions, type IgniterCallerResponseInterceptor, type IgniterCallerRetryOptions, type IgniterCallerSchemaMap, type IgniterCallerSchemaMethod, IgniterCallerSchemaUtils, type IgniterCallerSchemaValidationOptions, type IgniterCallerStoreAdapter, type IgniterCallerStoreOptions, type IgniterCallerUrlPattern, IgniterCallerUrlUtils, type InferAllResponseTypes, type InferRequestType, type InferResponseType };