@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.
- package/AGENTS.md +124 -0
- package/CHANGELOG.md +14 -0
- package/README.md +233 -0
- package/dist/index.d.mts +738 -0
- package/dist/index.d.ts +738 -0
- package/dist/index.js +1343 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1332 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/dist/index.d.mts
ADDED
|
@@ -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 };
|