@igniter-js/caller 0.1.2 → 0.1.4
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 +2275 -172
- package/CHANGELOG.md +13 -0
- package/README.md +108 -14
- package/dist/adapters/index.d.mts +1 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/adapters/index.js +91 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/index.mjs +89 -0
- package/dist/adapters/index.mjs.map +1 -0
- package/dist/index-COZVROi_.d.mts +121 -0
- package/dist/index-COZVROi_.d.ts +121 -0
- package/dist/index.d.mts +852 -288
- package/dist/index.d.ts +852 -288
- package/dist/index.js +992 -313
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +989 -314
- package/dist/index.mjs.map +1 -1
- package/dist/telemetry/index.d.mts +100 -0
- package/dist/telemetry/index.d.ts +100 -0
- package/dist/telemetry/index.js +54 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.mjs +52 -0
- package/dist/telemetry/index.mjs.map +1 -0
- package/package.json +24 -4
package/dist/index.js
CHANGED
|
@@ -1,112 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@igniter-js/core');
|
|
4
|
+
var zod = require('zod');
|
|
4
5
|
|
|
5
|
-
// src/
|
|
6
|
-
var
|
|
7
|
-
constructor(state, factory) {
|
|
8
|
-
this.state = state;
|
|
9
|
-
this.factory = factory;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Creates a new builder instance.
|
|
13
|
-
*/
|
|
14
|
-
static create(factory) {
|
|
15
|
-
return new _IgniterCallerBuilder({}, factory);
|
|
16
|
-
}
|
|
17
|
-
/** Sets the base URL for all requests. */
|
|
18
|
-
withBaseUrl(baseURL) {
|
|
19
|
-
return new _IgniterCallerBuilder({ ...this.state, baseURL }, this.factory);
|
|
20
|
-
}
|
|
21
|
-
/** Merges default headers for all requests. */
|
|
22
|
-
withHeaders(headers) {
|
|
23
|
-
return new _IgniterCallerBuilder({ ...this.state, headers }, this.factory);
|
|
24
|
-
}
|
|
25
|
-
/** Sets default cookies (sent as the `Cookie` header). */
|
|
26
|
-
withCookies(cookies) {
|
|
27
|
-
return new _IgniterCallerBuilder({ ...this.state, cookies }, this.factory);
|
|
28
|
-
}
|
|
29
|
-
/** Attaches a logger instance. */
|
|
30
|
-
withLogger(logger) {
|
|
31
|
-
return new _IgniterCallerBuilder({ ...this.state, logger }, this.factory);
|
|
32
|
-
}
|
|
33
|
-
/** Adds a request interceptor that runs before each request. */
|
|
34
|
-
withRequestInterceptor(interceptor) {
|
|
35
|
-
const requestInterceptors = [
|
|
36
|
-
...this.state.requestInterceptors || [],
|
|
37
|
-
interceptor
|
|
38
|
-
];
|
|
39
|
-
return new _IgniterCallerBuilder(
|
|
40
|
-
{ ...this.state, requestInterceptors },
|
|
41
|
-
this.factory
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
/** Adds a response interceptor that runs after each request. */
|
|
45
|
-
withResponseInterceptor(interceptor) {
|
|
46
|
-
const responseInterceptors = [
|
|
47
|
-
...this.state.responseInterceptors || [],
|
|
48
|
-
interceptor
|
|
49
|
-
];
|
|
50
|
-
return new _IgniterCallerBuilder(
|
|
51
|
-
{ ...this.state, responseInterceptors },
|
|
52
|
-
this.factory
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Configures a persistent store adapter for caching.
|
|
57
|
-
*
|
|
58
|
-
* When configured, cache operations will use the store (e.g., Redis)
|
|
59
|
-
* instead of in-memory cache, enabling persistent cache across deployments.
|
|
60
|
-
*/
|
|
61
|
-
withStore(store, options) {
|
|
62
|
-
return new _IgniterCallerBuilder(
|
|
63
|
-
{ ...this.state, store, storeOptions: options },
|
|
64
|
-
this.factory
|
|
65
|
-
);
|
|
66
|
-
}
|
|
6
|
+
// src/errors/caller.error.ts
|
|
7
|
+
var IgniterCallerError = class _IgniterCallerError extends core.IgniterError {
|
|
67
8
|
/**
|
|
68
|
-
*
|
|
9
|
+
* Creates a new typed caller error.
|
|
69
10
|
*
|
|
70
|
-
*
|
|
71
|
-
* route and method, with optional runtime validation via Zod.
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```ts
|
|
75
|
-
* const api = IgniterCaller.create()
|
|
76
|
-
* .withSchemas({
|
|
77
|
-
* '/users': {
|
|
78
|
-
* GET: {
|
|
79
|
-
* responses: {
|
|
80
|
-
* 200: z.array(UserSchema),
|
|
81
|
-
* 401: ErrorSchema,
|
|
82
|
-
* },
|
|
83
|
-
* },
|
|
84
|
-
* POST: {
|
|
85
|
-
* request: CreateUserSchema,
|
|
86
|
-
* responses: {
|
|
87
|
-
* 201: UserSchema,
|
|
88
|
-
* 400: ValidationErrorSchema,
|
|
89
|
-
* },
|
|
90
|
-
* },
|
|
91
|
-
* },
|
|
92
|
-
* })
|
|
93
|
-
* .build()
|
|
94
|
-
* ```
|
|
11
|
+
* @param payload - Error payload with code, message, and metadata.
|
|
95
12
|
*/
|
|
96
|
-
withSchemas(schemas, validation) {
|
|
97
|
-
return new _IgniterCallerBuilder(
|
|
98
|
-
{ ...this.state, schemas, schemaValidation: validation },
|
|
99
|
-
this.factory
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Builds the `IgniterCaller` instance.
|
|
104
|
-
*/
|
|
105
|
-
build() {
|
|
106
|
-
return this.factory(this.state);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
var IgniterCallerError = class _IgniterCallerError extends core.IgniterError {
|
|
110
13
|
constructor(payload) {
|
|
111
14
|
const metadata = {
|
|
112
15
|
...payload.metadata,
|
|
@@ -121,13 +24,19 @@ var IgniterCallerError = class _IgniterCallerError extends core.IgniterError {
|
|
|
121
24
|
causer: "@igniter-js/caller",
|
|
122
25
|
details,
|
|
123
26
|
metadata,
|
|
124
|
-
logger: payload.logger
|
|
27
|
+
logger: payload.logger,
|
|
28
|
+
cause: payload.cause
|
|
125
29
|
});
|
|
126
30
|
this.name = "IgniterCallerError";
|
|
127
31
|
this.operation = payload.operation;
|
|
128
32
|
this.statusText = payload.statusText;
|
|
129
33
|
this.cause = payload.cause;
|
|
130
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Type guard for `IgniterCallerError`.
|
|
37
|
+
*
|
|
38
|
+
* @param error - Value to check.
|
|
39
|
+
*/
|
|
131
40
|
static is(error) {
|
|
132
41
|
return error instanceof _IgniterCallerError;
|
|
133
42
|
}
|
|
@@ -137,6 +46,9 @@ var IgniterCallerError = class _IgniterCallerError extends core.IgniterError {
|
|
|
137
46
|
var IgniterCallerBodyUtils = class {
|
|
138
47
|
/**
|
|
139
48
|
* Returns true when the request body should be passed to `fetch` as-is.
|
|
49
|
+
*
|
|
50
|
+
* @param body - Request body to inspect.
|
|
51
|
+
* @returns True if the body should be sent as raw data.
|
|
140
52
|
*/
|
|
141
53
|
static isRawBody(body) {
|
|
142
54
|
if (!body) return false;
|
|
@@ -155,6 +67,10 @@ var IgniterCallerBodyUtils = class {
|
|
|
155
67
|
}
|
|
156
68
|
/**
|
|
157
69
|
* Removes Content-Type for FormData so fetch can set boundaries automatically.
|
|
70
|
+
*
|
|
71
|
+
* @param headers - Request headers map.
|
|
72
|
+
* @param body - Request body.
|
|
73
|
+
* @returns Updated headers without Content-Type when needed.
|
|
158
74
|
*/
|
|
159
75
|
static normalizeHeadersForBody(headers, body) {
|
|
160
76
|
if (!headers) return headers;
|
|
@@ -173,6 +89,9 @@ var _IgniterCallerCacheUtils = class _IgniterCallerCacheUtils {
|
|
|
173
89
|
*
|
|
174
90
|
* When configured, cache operations will use the store (e.g., Redis)
|
|
175
91
|
* instead of in-memory cache, enabling persistent cache across deployments.
|
|
92
|
+
*
|
|
93
|
+
* @param store - Store adapter implementation.
|
|
94
|
+
* @param options - Store options such as ttl and key prefix.
|
|
176
95
|
*/
|
|
177
96
|
static setStore(store, options) {
|
|
178
97
|
_IgniterCallerCacheUtils.store = store;
|
|
@@ -185,12 +104,18 @@ var _IgniterCallerCacheUtils = class _IgniterCallerCacheUtils {
|
|
|
185
104
|
}
|
|
186
105
|
/**
|
|
187
106
|
* Gets the configured store adapter.
|
|
107
|
+
*
|
|
108
|
+
* @returns Store adapter or null when unset.
|
|
188
109
|
*/
|
|
189
110
|
static getStore() {
|
|
190
111
|
return _IgniterCallerCacheUtils.store;
|
|
191
112
|
}
|
|
192
113
|
/**
|
|
193
114
|
* Gets cached data if it exists and is not stale.
|
|
115
|
+
*
|
|
116
|
+
* @param key - Cache key (without prefix).
|
|
117
|
+
* @param staleTime - Optional stale time in milliseconds.
|
|
118
|
+
* @returns Cached value or undefined when missing/stale.
|
|
194
119
|
*/
|
|
195
120
|
static async get(key, staleTime) {
|
|
196
121
|
const prefixedKey = _IgniterCallerCacheUtils.getPrefixedKey(key);
|
|
@@ -214,6 +139,10 @@ var _IgniterCallerCacheUtils = class _IgniterCallerCacheUtils {
|
|
|
214
139
|
}
|
|
215
140
|
/**
|
|
216
141
|
* Stores data in cache with current timestamp.
|
|
142
|
+
*
|
|
143
|
+
* @param key - Cache key (without prefix).
|
|
144
|
+
* @param data - Data to cache.
|
|
145
|
+
* @param ttl - Optional TTL override in seconds.
|
|
217
146
|
*/
|
|
218
147
|
static async set(key, data, ttl) {
|
|
219
148
|
const prefixedKey = _IgniterCallerCacheUtils.getPrefixedKey(key);
|
|
@@ -235,6 +164,8 @@ var _IgniterCallerCacheUtils = class _IgniterCallerCacheUtils {
|
|
|
235
164
|
}
|
|
236
165
|
/**
|
|
237
166
|
* Clears a specific cache entry.
|
|
167
|
+
*
|
|
168
|
+
* @param key - Cache key (without prefix).
|
|
238
169
|
*/
|
|
239
170
|
static async clear(key) {
|
|
240
171
|
const prefixedKey = _IgniterCallerCacheUtils.getPrefixedKey(key);
|
|
@@ -268,6 +199,8 @@ var _IgniterCallerCacheUtils = class _IgniterCallerCacheUtils {
|
|
|
268
199
|
}
|
|
269
200
|
/**
|
|
270
201
|
* Clears all cache entries.
|
|
202
|
+
*
|
|
203
|
+
* @returns Promise that resolves when in-memory cache is cleared.
|
|
271
204
|
*/
|
|
272
205
|
static async clearAll() {
|
|
273
206
|
_IgniterCallerCacheUtils.cache.clear();
|
|
@@ -306,6 +239,10 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
306
239
|
/**
|
|
307
240
|
* Matches a URL path against schema map paths (supports path parameters).
|
|
308
241
|
*
|
|
242
|
+
* @param actualPath - Incoming request path.
|
|
243
|
+
* @param schemaPath - Schema path pattern.
|
|
244
|
+
* @returns Match result with params when matched.
|
|
245
|
+
*
|
|
309
246
|
* @example
|
|
310
247
|
* ```ts
|
|
311
248
|
* matchPath('/users/123', '/users/:id') // { matched: true, params: { id: '123' } }
|
|
@@ -334,6 +271,11 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
334
271
|
}
|
|
335
272
|
/**
|
|
336
273
|
* Finds the schema for a given path and method from the schema map.
|
|
274
|
+
*
|
|
275
|
+
* @param schemaMap - Schema map from the builder.
|
|
276
|
+
* @param path - Request path to match.
|
|
277
|
+
* @param method - HTTP method to match.
|
|
278
|
+
* @returns Matching schema and extracted params.
|
|
337
279
|
*/
|
|
338
280
|
static findSchema(schemaMap, path, method) {
|
|
339
281
|
if (!schemaMap) {
|
|
@@ -359,6 +301,10 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
359
301
|
*
|
|
360
302
|
* If the schema provides `~standard.validate`, it will be used.
|
|
361
303
|
* Otherwise, returns the input as-is.
|
|
304
|
+
*
|
|
305
|
+
* @param schema - StandardSchema instance.
|
|
306
|
+
* @param input - Input value to validate.
|
|
307
|
+
* @returns Validated input value.
|
|
362
308
|
*/
|
|
363
309
|
static async validateWithStandardSchema(schema, input) {
|
|
364
310
|
const standard = schema?.["~standard"];
|
|
@@ -377,7 +323,12 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
377
323
|
/**
|
|
378
324
|
* Validates request body against schema.
|
|
379
325
|
*
|
|
380
|
-
* @
|
|
326
|
+
* @param data - Request body data.
|
|
327
|
+
* @param schema - Request schema (if any).
|
|
328
|
+
* @param options - Validation options.
|
|
329
|
+
* @param context - Request context for error reporting.
|
|
330
|
+
* @param logger - Optional logger instance.
|
|
331
|
+
* @returns Validated data or throws/logs error based on validation mode.
|
|
381
332
|
*/
|
|
382
333
|
static async validateRequest(data, schema, options, context, logger) {
|
|
383
334
|
if (!schema || options?.mode === "off") {
|
|
@@ -410,7 +361,13 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
410
361
|
/**
|
|
411
362
|
* Validates response data against schema.
|
|
412
363
|
*
|
|
413
|
-
* @
|
|
364
|
+
* @param data - Response payload to validate.
|
|
365
|
+
* @param schema - Response schema (if any).
|
|
366
|
+
* @param statusCode - HTTP status code.
|
|
367
|
+
* @param options - Validation options.
|
|
368
|
+
* @param context - Request context for error reporting.
|
|
369
|
+
* @param logger - Optional logger instance.
|
|
370
|
+
* @returns Validated data or throws/logs error based on validation mode.
|
|
414
371
|
*/
|
|
415
372
|
static async validateResponse(data, schema, statusCode, options, context, logger) {
|
|
416
373
|
if (!schema || options?.mode === "off") {
|
|
@@ -445,6 +402,12 @@ var IgniterCallerSchemaUtils = class _IgniterCallerSchemaUtils {
|
|
|
445
402
|
|
|
446
403
|
// src/utils/url.ts
|
|
447
404
|
var IgniterCallerUrlUtils = class {
|
|
405
|
+
/**
|
|
406
|
+
* Builds a full URL with optional base URL and query parameters.
|
|
407
|
+
*
|
|
408
|
+
* @param params - URL construction parameters.
|
|
409
|
+
* @returns Full URL string.
|
|
410
|
+
*/
|
|
448
411
|
static buildUrl(params) {
|
|
449
412
|
const { url, baseURL, query } = params;
|
|
450
413
|
let fullUrl = url;
|
|
@@ -461,7 +424,7 @@ var IgniterCallerUrlUtils = class {
|
|
|
461
424
|
}
|
|
462
425
|
};
|
|
463
426
|
|
|
464
|
-
// src/
|
|
427
|
+
// src/builders/request.builder.ts
|
|
465
428
|
var VALIDATABLE_CONTENT_TYPES = [
|
|
466
429
|
"json",
|
|
467
430
|
"xml",
|
|
@@ -509,6 +472,11 @@ async function parseResponseByContentType(response, contentType) {
|
|
|
509
472
|
}
|
|
510
473
|
}
|
|
511
474
|
var IgniterCallerRequestBuilder = class {
|
|
475
|
+
/**
|
|
476
|
+
* Creates a new request builder instance.
|
|
477
|
+
*
|
|
478
|
+
* @param params - Builder configuration from the manager.
|
|
479
|
+
*/
|
|
512
480
|
constructor(params) {
|
|
513
481
|
this.options = {
|
|
514
482
|
method: "GET",
|
|
@@ -531,6 +499,7 @@ var IgniterCallerRequestBuilder = class {
|
|
|
531
499
|
this.options.headers = { ...this.options.headers, Cookie: cookieStr };
|
|
532
500
|
}
|
|
533
501
|
this.logger = params.logger;
|
|
502
|
+
this.telemetry = params.telemetry;
|
|
534
503
|
this.requestInterceptors = params.requestInterceptors;
|
|
535
504
|
this.responseInterceptors = params.responseInterceptors;
|
|
536
505
|
this.eventEmitter = params.eventEmitter;
|
|
@@ -540,6 +509,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
540
509
|
/**
|
|
541
510
|
* Sets the HTTP method for this request.
|
|
542
511
|
* @internal Used by IgniterCaller.request() for generic requests.
|
|
512
|
+
*
|
|
513
|
+
* @param method - HTTP method for the request.
|
|
543
514
|
*/
|
|
544
515
|
_setMethod(method) {
|
|
545
516
|
this.options.method = method;
|
|
@@ -548,6 +519,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
548
519
|
/**
|
|
549
520
|
* Sets the URL for this request.
|
|
550
521
|
* @internal Used when URL is passed to HTTP method directly.
|
|
522
|
+
*
|
|
523
|
+
* @param url - Request URL or path.
|
|
551
524
|
*/
|
|
552
525
|
_setUrl(url) {
|
|
553
526
|
this.options.url = url;
|
|
@@ -555,6 +528,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
555
528
|
}
|
|
556
529
|
/**
|
|
557
530
|
* Overrides the logger for this request chain.
|
|
531
|
+
*
|
|
532
|
+
* @param logger - Logger implementation from `@igniter-js/core`.
|
|
558
533
|
*/
|
|
559
534
|
withLogger(logger) {
|
|
560
535
|
this.logger = logger;
|
|
@@ -562,6 +537,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
562
537
|
}
|
|
563
538
|
/**
|
|
564
539
|
* Sets the request URL.
|
|
540
|
+
*
|
|
541
|
+
* @param url - Request URL or path.
|
|
565
542
|
*/
|
|
566
543
|
url(url) {
|
|
567
544
|
this.options.url = url;
|
|
@@ -570,6 +547,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
570
547
|
/**
|
|
571
548
|
* Sets the request body.
|
|
572
549
|
* For GET/HEAD requests, body will be automatically converted to query params.
|
|
550
|
+
*
|
|
551
|
+
* @param body - Body payload for the request.
|
|
573
552
|
*/
|
|
574
553
|
body(body) {
|
|
575
554
|
this.options.body = body;
|
|
@@ -577,6 +556,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
577
556
|
}
|
|
578
557
|
/**
|
|
579
558
|
* Sets URL query parameters.
|
|
559
|
+
*
|
|
560
|
+
* @param params - Query string parameters.
|
|
580
561
|
*/
|
|
581
562
|
params(params) {
|
|
582
563
|
this.options.params = params;
|
|
@@ -584,6 +565,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
584
565
|
}
|
|
585
566
|
/**
|
|
586
567
|
* Merges additional headers into the request.
|
|
568
|
+
*
|
|
569
|
+
* @param headers - Header map merged into existing headers.
|
|
587
570
|
*/
|
|
588
571
|
headers(headers) {
|
|
589
572
|
this.options.headers = { ...this.options.headers, ...headers };
|
|
@@ -591,6 +574,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
591
574
|
}
|
|
592
575
|
/**
|
|
593
576
|
* Sets request timeout in milliseconds.
|
|
577
|
+
*
|
|
578
|
+
* @param timeout - Timeout in milliseconds.
|
|
594
579
|
*/
|
|
595
580
|
timeout(timeout) {
|
|
596
581
|
this.options.timeout = timeout;
|
|
@@ -598,6 +583,9 @@ var IgniterCallerRequestBuilder = class {
|
|
|
598
583
|
}
|
|
599
584
|
/**
|
|
600
585
|
* Sets cache strategy and optional cache key.
|
|
586
|
+
*
|
|
587
|
+
* @param cache - Cache strategy for the request.
|
|
588
|
+
* @param key - Optional cache key override.
|
|
601
589
|
*/
|
|
602
590
|
cache(cache, key) {
|
|
603
591
|
this.options.cache = cache;
|
|
@@ -606,6 +594,9 @@ var IgniterCallerRequestBuilder = class {
|
|
|
606
594
|
}
|
|
607
595
|
/**
|
|
608
596
|
* Configures retry behavior for failed requests.
|
|
597
|
+
*
|
|
598
|
+
* @param maxAttempts - Maximum number of attempts.
|
|
599
|
+
* @param options - Retry options excluding `maxAttempts`.
|
|
609
600
|
*/
|
|
610
601
|
retry(maxAttempts, options) {
|
|
611
602
|
this.retryOptions = { maxAttempts, ...options };
|
|
@@ -613,6 +604,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
613
604
|
}
|
|
614
605
|
/**
|
|
615
606
|
* Provides a fallback value if the request fails.
|
|
607
|
+
*
|
|
608
|
+
* @param fn - Fallback factory called when the request fails.
|
|
616
609
|
*/
|
|
617
610
|
fallback(fn) {
|
|
618
611
|
this.fallbackFn = fn;
|
|
@@ -620,6 +613,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
620
613
|
}
|
|
621
614
|
/**
|
|
622
615
|
* Sets cache stale time in milliseconds.
|
|
616
|
+
*
|
|
617
|
+
* @param milliseconds - Stale time in milliseconds.
|
|
623
618
|
*/
|
|
624
619
|
stale(milliseconds) {
|
|
625
620
|
this.staleTime = milliseconds;
|
|
@@ -633,6 +628,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
633
628
|
*
|
|
634
629
|
* The actual parsing is based on Content-Type headers, not this setting.
|
|
635
630
|
*
|
|
631
|
+
* @param schema - Zod/StandardSchema instance for validation (optional).
|
|
632
|
+
*
|
|
636
633
|
* @example
|
|
637
634
|
* ```ts
|
|
638
635
|
* // With Zod schema (validates JSON response)
|
|
@@ -651,6 +648,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
651
648
|
/**
|
|
652
649
|
* Downloads a file via GET request.
|
|
653
650
|
* @deprecated Use `.responseType<File>().execute()` instead. The response type is auto-detected.
|
|
651
|
+
*
|
|
652
|
+
* @param url - URL or path to download.
|
|
654
653
|
*/
|
|
655
654
|
getFile(url) {
|
|
656
655
|
this.options.method = "GET";
|
|
@@ -725,7 +724,7 @@ var IgniterCallerRequestBuilder = class {
|
|
|
725
724
|
statusCode: 408,
|
|
726
725
|
logger: this.logger,
|
|
727
726
|
metadata: { url: finalUrl },
|
|
728
|
-
cause: error
|
|
727
|
+
cause: error instanceof Error ? error : void 0
|
|
729
728
|
})
|
|
730
729
|
};
|
|
731
730
|
}
|
|
@@ -737,7 +736,7 @@ var IgniterCallerRequestBuilder = class {
|
|
|
737
736
|
message: error?.message || "Failed to download file",
|
|
738
737
|
logger: this.logger,
|
|
739
738
|
metadata: { url: finalUrl },
|
|
740
|
-
cause: error
|
|
739
|
+
cause: error instanceof Error ? error : void 0
|
|
741
740
|
})
|
|
742
741
|
};
|
|
743
742
|
}
|
|
@@ -756,8 +755,32 @@ var IgniterCallerRequestBuilder = class {
|
|
|
756
755
|
* - `application/octet-stream` → returned as Blob
|
|
757
756
|
*
|
|
758
757
|
* Schema validation (if configured) only runs for validatable content types (JSON, XML, CSV).
|
|
758
|
+
*
|
|
759
|
+
* @returns Response envelope with data or error.
|
|
759
760
|
*/
|
|
760
761
|
async execute() {
|
|
762
|
+
const startTime = Date.now();
|
|
763
|
+
const { safeUrl } = this.resolveUrl();
|
|
764
|
+
const method = this.options.method;
|
|
765
|
+
const baseURL = this.options.baseURL;
|
|
766
|
+
const timeoutMs = this.options.timeout;
|
|
767
|
+
this.telemetry?.emit(
|
|
768
|
+
"igniter.caller.request.execute.started",
|
|
769
|
+
{
|
|
770
|
+
level: "debug",
|
|
771
|
+
attributes: {
|
|
772
|
+
"ctx.request.method": method,
|
|
773
|
+
"ctx.request.url": safeUrl,
|
|
774
|
+
"ctx.request.baseUrl": baseURL,
|
|
775
|
+
"ctx.request.timeoutMs": timeoutMs
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
this.logger?.debug("IgniterCaller.request.execute started", {
|
|
780
|
+
method,
|
|
781
|
+
url: safeUrl,
|
|
782
|
+
baseURL
|
|
783
|
+
});
|
|
761
784
|
const effectiveCacheKey = this.cacheKey || this.options.url;
|
|
762
785
|
if (effectiveCacheKey && this.staleTime) {
|
|
763
786
|
const cached = await IgniterCallerCacheUtils.get(
|
|
@@ -765,8 +788,36 @@ var IgniterCallerRequestBuilder = class {
|
|
|
765
788
|
this.staleTime
|
|
766
789
|
);
|
|
767
790
|
if (cached !== void 0) {
|
|
768
|
-
this.
|
|
769
|
-
|
|
791
|
+
this.telemetry?.emit(
|
|
792
|
+
"igniter.caller.cache.read.hit",
|
|
793
|
+
{
|
|
794
|
+
level: "debug",
|
|
795
|
+
attributes: {
|
|
796
|
+
"ctx.request.method": method,
|
|
797
|
+
"ctx.request.url": safeUrl,
|
|
798
|
+
"ctx.cache.key": effectiveCacheKey,
|
|
799
|
+
"ctx.cache.staleTime": this.staleTime
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
);
|
|
803
|
+
const durationMs2 = Date.now() - startTime;
|
|
804
|
+
this.telemetry?.emit(
|
|
805
|
+
"igniter.caller.request.execute.success",
|
|
806
|
+
{
|
|
807
|
+
level: "info",
|
|
808
|
+
attributes: {
|
|
809
|
+
"ctx.request.method": method,
|
|
810
|
+
"ctx.request.url": safeUrl,
|
|
811
|
+
"ctx.request.durationMs": durationMs2,
|
|
812
|
+
"ctx.cache.hit": true
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
);
|
|
816
|
+
this.logger?.info("IgniterCaller.request.execute success (cache)", {
|
|
817
|
+
key: effectiveCacheKey,
|
|
818
|
+
method,
|
|
819
|
+
url: safeUrl,
|
|
820
|
+
durationMs: durationMs2
|
|
770
821
|
});
|
|
771
822
|
const cachedResult = {
|
|
772
823
|
data: cached,
|
|
@@ -778,13 +829,33 @@ var IgniterCallerRequestBuilder = class {
|
|
|
778
829
|
}
|
|
779
830
|
const result = await this.executeWithRetry();
|
|
780
831
|
if (result.error && this.fallbackFn) {
|
|
781
|
-
this.logger?.debug("IgniterCaller.execute applying fallback", {
|
|
832
|
+
this.logger?.debug("IgniterCaller.request.execute applying fallback", {
|
|
833
|
+
method,
|
|
834
|
+
url: safeUrl,
|
|
782
835
|
error: result.error
|
|
783
836
|
});
|
|
784
837
|
const fallbackResult = {
|
|
785
838
|
data: this.fallbackFn(),
|
|
786
839
|
error: void 0
|
|
787
840
|
};
|
|
841
|
+
const durationMs2 = Date.now() - startTime;
|
|
842
|
+
this.telemetry?.emit(
|
|
843
|
+
"igniter.caller.request.execute.success",
|
|
844
|
+
{
|
|
845
|
+
level: "info",
|
|
846
|
+
attributes: {
|
|
847
|
+
"ctx.request.method": method,
|
|
848
|
+
"ctx.request.url": safeUrl,
|
|
849
|
+
"ctx.request.durationMs": durationMs2,
|
|
850
|
+
"ctx.request.fallback": true
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
);
|
|
854
|
+
this.logger?.info("IgniterCaller.request.execute success (fallback)", {
|
|
855
|
+
method,
|
|
856
|
+
url: safeUrl,
|
|
857
|
+
durationMs: durationMs2
|
|
858
|
+
});
|
|
788
859
|
await this.emitEvent(fallbackResult);
|
|
789
860
|
return fallbackResult;
|
|
790
861
|
}
|
|
@@ -795,12 +866,57 @@ var IgniterCallerRequestBuilder = class {
|
|
|
795
866
|
this.staleTime
|
|
796
867
|
);
|
|
797
868
|
}
|
|
869
|
+
const durationMs = Date.now() - startTime;
|
|
870
|
+
if (result.error) {
|
|
871
|
+
this.telemetry?.emit(
|
|
872
|
+
"igniter.caller.request.execute.error",
|
|
873
|
+
{
|
|
874
|
+
level: "error",
|
|
875
|
+
attributes: {
|
|
876
|
+
"ctx.request.method": method,
|
|
877
|
+
"ctx.request.url": safeUrl,
|
|
878
|
+
"ctx.request.durationMs": durationMs,
|
|
879
|
+
"ctx.error.code": result.error instanceof IgniterCallerError ? result.error.code : "IGNITER_CALLER_UNKNOWN_ERROR",
|
|
880
|
+
"ctx.error.message": result.error.message,
|
|
881
|
+
"ctx.response.status": result.status
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
);
|
|
885
|
+
this.logger?.error("IgniterCaller.request.execute failed", {
|
|
886
|
+
method,
|
|
887
|
+
url: safeUrl,
|
|
888
|
+
durationMs,
|
|
889
|
+
error: result.error
|
|
890
|
+
});
|
|
891
|
+
} else {
|
|
892
|
+
const contentType = result.headers?.get("content-type") || void 0;
|
|
893
|
+
this.telemetry?.emit(
|
|
894
|
+
"igniter.caller.request.execute.success",
|
|
895
|
+
{
|
|
896
|
+
level: "info",
|
|
897
|
+
attributes: {
|
|
898
|
+
"ctx.request.method": method,
|
|
899
|
+
"ctx.request.url": safeUrl,
|
|
900
|
+
"ctx.request.durationMs": durationMs,
|
|
901
|
+
"ctx.response.status": result.status,
|
|
902
|
+
"ctx.response.contentType": contentType,
|
|
903
|
+
"ctx.cache.hit": false
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
);
|
|
907
|
+
this.logger?.info("IgniterCaller.request.execute success", {
|
|
908
|
+
method,
|
|
909
|
+
url: safeUrl,
|
|
910
|
+
durationMs,
|
|
911
|
+
status: result.status
|
|
912
|
+
});
|
|
913
|
+
}
|
|
798
914
|
await this.emitEvent(result);
|
|
799
915
|
return result;
|
|
800
916
|
}
|
|
801
917
|
async executeWithRetry() {
|
|
802
918
|
const maxAttempts = this.retryOptions?.maxAttempts || 1;
|
|
803
|
-
const baseDelay = this.retryOptions?.baseDelay
|
|
919
|
+
const baseDelay = this.retryOptions?.baseDelay ?? 1e3;
|
|
804
920
|
const backoff = this.retryOptions?.backoff || "linear";
|
|
805
921
|
const retryOnStatus = this.retryOptions?.retryOnStatus || [
|
|
806
922
|
408,
|
|
@@ -810,13 +926,30 @@ var IgniterCallerRequestBuilder = class {
|
|
|
810
926
|
503,
|
|
811
927
|
504
|
|
812
928
|
];
|
|
929
|
+
const { safeUrl } = this.resolveUrl();
|
|
930
|
+
const method = this.options.method;
|
|
813
931
|
let lastError;
|
|
814
932
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
815
933
|
if (attempt > 0) {
|
|
816
934
|
const delay = backoff === "exponential" ? baseDelay * 2 ** (attempt - 1) : baseDelay * attempt;
|
|
817
|
-
this.
|
|
818
|
-
attempt,
|
|
819
|
-
|
|
935
|
+
this.telemetry?.emit(
|
|
936
|
+
"igniter.caller.retry.attempt.started",
|
|
937
|
+
{
|
|
938
|
+
level: "debug",
|
|
939
|
+
attributes: {
|
|
940
|
+
"ctx.request.method": method,
|
|
941
|
+
"ctx.request.url": safeUrl,
|
|
942
|
+
"ctx.retry.attempt": attempt + 1,
|
|
943
|
+
"ctx.retry.maxAttempts": maxAttempts,
|
|
944
|
+
"ctx.retry.delayMs": delay
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
);
|
|
948
|
+
this.logger?.debug("IgniterCaller.request.execute retrying", {
|
|
949
|
+
method,
|
|
950
|
+
url: safeUrl,
|
|
951
|
+
attempt: attempt + 1,
|
|
952
|
+
delayMs: delay
|
|
820
953
|
});
|
|
821
954
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
822
955
|
}
|
|
@@ -837,10 +970,8 @@ var IgniterCallerRequestBuilder = class {
|
|
|
837
970
|
}
|
|
838
971
|
async executeSingleRequest() {
|
|
839
972
|
let { url, requestInit, controller, timeoutId } = this.buildRequest();
|
|
840
|
-
this.
|
|
841
|
-
|
|
842
|
-
url
|
|
843
|
-
});
|
|
973
|
+
const { safeUrl } = this.resolveUrl();
|
|
974
|
+
const method = this.options.method;
|
|
844
975
|
if (this.requestInterceptors && this.requestInterceptors.length > 0) {
|
|
845
976
|
let modifiedOptions = { ...this.options, url };
|
|
846
977
|
for (const interceptor of this.requestInterceptors) {
|
|
@@ -870,9 +1001,27 @@ var IgniterCallerRequestBuilder = class {
|
|
|
870
1001
|
);
|
|
871
1002
|
} catch (error) {
|
|
872
1003
|
clearTimeout(timeoutId);
|
|
1004
|
+
const err = error;
|
|
1005
|
+
this.telemetry?.emit(
|
|
1006
|
+
"igniter.caller.validation.request.error",
|
|
1007
|
+
{
|
|
1008
|
+
level: "error",
|
|
1009
|
+
attributes: {
|
|
1010
|
+
"ctx.request.method": method,
|
|
1011
|
+
"ctx.request.url": safeUrl,
|
|
1012
|
+
"ctx.validation.type": "request",
|
|
1013
|
+
"ctx.validation.error": err.message
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
);
|
|
1017
|
+
this.logger?.error("IgniterCaller.request.validation failed", {
|
|
1018
|
+
method,
|
|
1019
|
+
url: safeUrl,
|
|
1020
|
+
error: err
|
|
1021
|
+
});
|
|
873
1022
|
return {
|
|
874
1023
|
data: void 0,
|
|
875
|
-
error
|
|
1024
|
+
error: err
|
|
876
1025
|
};
|
|
877
1026
|
}
|
|
878
1027
|
}
|
|
@@ -926,9 +1075,29 @@ var IgniterCallerRequestBuilder = class {
|
|
|
926
1075
|
this.logger
|
|
927
1076
|
);
|
|
928
1077
|
} catch (error) {
|
|
1078
|
+
const err = error;
|
|
1079
|
+
this.telemetry?.emit(
|
|
1080
|
+
"igniter.caller.validation.response.error",
|
|
1081
|
+
{
|
|
1082
|
+
level: "error",
|
|
1083
|
+
attributes: {
|
|
1084
|
+
"ctx.request.method": method,
|
|
1085
|
+
"ctx.request.url": safeUrl,
|
|
1086
|
+
"ctx.validation.type": "response",
|
|
1087
|
+
"ctx.validation.error": err.message,
|
|
1088
|
+
"ctx.response.status": httpResponse.status
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
);
|
|
1092
|
+
this.logger?.error("IgniterCaller.response.validation failed", {
|
|
1093
|
+
method,
|
|
1094
|
+
url: safeUrl,
|
|
1095
|
+
status: httpResponse.status,
|
|
1096
|
+
error: err
|
|
1097
|
+
});
|
|
929
1098
|
return {
|
|
930
1099
|
data: void 0,
|
|
931
|
-
error,
|
|
1100
|
+
error: err,
|
|
932
1101
|
status: httpResponse.status,
|
|
933
1102
|
headers: httpResponse.headers
|
|
934
1103
|
};
|
|
@@ -940,20 +1109,40 @@ var IgniterCallerRequestBuilder = class {
|
|
|
940
1109
|
const zodSchema = this.responseTypeSchema;
|
|
941
1110
|
const result = zodSchema.safeParse(data);
|
|
942
1111
|
if (!result.success) {
|
|
1112
|
+
const err = new IgniterCallerError({
|
|
1113
|
+
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
1114
|
+
operation: "parseResponse",
|
|
1115
|
+
message: `Response validation failed: ${result.error.message}`,
|
|
1116
|
+
logger: this.logger,
|
|
1117
|
+
statusCode: httpResponse.status,
|
|
1118
|
+
metadata: {
|
|
1119
|
+
method: this.options.method,
|
|
1120
|
+
url
|
|
1121
|
+
},
|
|
1122
|
+
cause: result.error
|
|
1123
|
+
});
|
|
1124
|
+
this.telemetry?.emit(
|
|
1125
|
+
"igniter.caller.validation.response.error",
|
|
1126
|
+
{
|
|
1127
|
+
level: "error",
|
|
1128
|
+
attributes: {
|
|
1129
|
+
"ctx.request.method": method,
|
|
1130
|
+
"ctx.request.url": safeUrl,
|
|
1131
|
+
"ctx.validation.type": "response",
|
|
1132
|
+
"ctx.validation.error": err.message,
|
|
1133
|
+
"ctx.response.status": httpResponse.status
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
);
|
|
1137
|
+
this.logger?.error("IgniterCaller.response.validation failed", {
|
|
1138
|
+
method,
|
|
1139
|
+
url: safeUrl,
|
|
1140
|
+
status: httpResponse.status,
|
|
1141
|
+
error: err
|
|
1142
|
+
});
|
|
943
1143
|
return {
|
|
944
1144
|
data: void 0,
|
|
945
|
-
error:
|
|
946
|
-
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
947
|
-
operation: "parseResponse",
|
|
948
|
-
message: `Response validation failed: ${result.error.message}`,
|
|
949
|
-
logger: this.logger,
|
|
950
|
-
statusCode: httpResponse.status,
|
|
951
|
-
metadata: {
|
|
952
|
-
method: this.options.method,
|
|
953
|
-
url
|
|
954
|
-
},
|
|
955
|
-
cause: result.error
|
|
956
|
-
}),
|
|
1145
|
+
error: err,
|
|
957
1146
|
status: httpResponse.status,
|
|
958
1147
|
headers: httpResponse.headers
|
|
959
1148
|
};
|
|
@@ -964,40 +1153,80 @@ var IgniterCallerRequestBuilder = class {
|
|
|
964
1153
|
const standardSchema = this.responseTypeSchema;
|
|
965
1154
|
const result = await standardSchema["~standard"].validate(data);
|
|
966
1155
|
if (result.issues) {
|
|
1156
|
+
const err = new IgniterCallerError({
|
|
1157
|
+
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
1158
|
+
operation: "parseResponse",
|
|
1159
|
+
message: `Response validation failed`,
|
|
1160
|
+
logger: this.logger,
|
|
1161
|
+
statusCode: httpResponse.status,
|
|
1162
|
+
metadata: {
|
|
1163
|
+
method: this.options.method,
|
|
1164
|
+
url,
|
|
1165
|
+
issues: result.issues
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
this.telemetry?.emit(
|
|
1169
|
+
"igniter.caller.validation.response.error",
|
|
1170
|
+
{
|
|
1171
|
+
level: "error",
|
|
1172
|
+
attributes: {
|
|
1173
|
+
"ctx.request.method": method,
|
|
1174
|
+
"ctx.request.url": safeUrl,
|
|
1175
|
+
"ctx.validation.type": "response",
|
|
1176
|
+
"ctx.validation.error": err.message,
|
|
1177
|
+
"ctx.response.status": httpResponse.status
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
);
|
|
1181
|
+
this.logger?.error("IgniterCaller.response.validation failed", {
|
|
1182
|
+
method,
|
|
1183
|
+
url: safeUrl,
|
|
1184
|
+
status: httpResponse.status,
|
|
1185
|
+
error: err
|
|
1186
|
+
});
|
|
967
1187
|
return {
|
|
968
1188
|
data: void 0,
|
|
969
|
-
error:
|
|
970
|
-
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
971
|
-
operation: "parseResponse",
|
|
972
|
-
message: `Response validation failed`,
|
|
973
|
-
logger: this.logger,
|
|
974
|
-
statusCode: httpResponse.status,
|
|
975
|
-
metadata: {
|
|
976
|
-
method: this.options.method,
|
|
977
|
-
url,
|
|
978
|
-
issues: result.issues
|
|
979
|
-
}
|
|
980
|
-
}),
|
|
1189
|
+
error: err,
|
|
981
1190
|
status: httpResponse.status,
|
|
982
1191
|
headers: httpResponse.headers
|
|
983
1192
|
};
|
|
984
1193
|
}
|
|
985
1194
|
data = result.value;
|
|
986
1195
|
} catch (error) {
|
|
1196
|
+
const err = new IgniterCallerError({
|
|
1197
|
+
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
1198
|
+
operation: "parseResponse",
|
|
1199
|
+
message: error?.message || "Response validation failed",
|
|
1200
|
+
logger: this.logger,
|
|
1201
|
+
statusCode: httpResponse.status,
|
|
1202
|
+
metadata: {
|
|
1203
|
+
method: this.options.method,
|
|
1204
|
+
url
|
|
1205
|
+
},
|
|
1206
|
+
cause: error instanceof Error ? error : void 0
|
|
1207
|
+
});
|
|
1208
|
+
this.telemetry?.emit(
|
|
1209
|
+
"igniter.caller.validation.response.error",
|
|
1210
|
+
{
|
|
1211
|
+
level: "error",
|
|
1212
|
+
attributes: {
|
|
1213
|
+
"ctx.request.method": method,
|
|
1214
|
+
"ctx.request.url": safeUrl,
|
|
1215
|
+
"ctx.validation.type": "response",
|
|
1216
|
+
"ctx.validation.error": err.message,
|
|
1217
|
+
"ctx.response.status": httpResponse.status
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
);
|
|
1221
|
+
this.logger?.error("IgniterCaller.response.validation failed", {
|
|
1222
|
+
method,
|
|
1223
|
+
url: safeUrl,
|
|
1224
|
+
status: httpResponse.status,
|
|
1225
|
+
error: err
|
|
1226
|
+
});
|
|
987
1227
|
return {
|
|
988
1228
|
data: void 0,
|
|
989
|
-
error:
|
|
990
|
-
code: "IGNITER_CALLER_RESPONSE_VALIDATION_FAILED",
|
|
991
|
-
operation: "parseResponse",
|
|
992
|
-
message: error?.message || "Response validation failed",
|
|
993
|
-
logger: this.logger,
|
|
994
|
-
statusCode: httpResponse.status,
|
|
995
|
-
metadata: {
|
|
996
|
-
method: this.options.method,
|
|
997
|
-
url
|
|
998
|
-
},
|
|
999
|
-
cause: error
|
|
1000
|
-
}),
|
|
1229
|
+
error: err,
|
|
1001
1230
|
status: httpResponse.status,
|
|
1002
1231
|
headers: httpResponse.headers
|
|
1003
1232
|
};
|
|
@@ -1020,20 +1249,38 @@ var IgniterCallerRequestBuilder = class {
|
|
|
1020
1249
|
} catch (error) {
|
|
1021
1250
|
clearTimeout(timeoutId);
|
|
1022
1251
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1252
|
+
const err = new IgniterCallerError({
|
|
1253
|
+
code: "IGNITER_CALLER_TIMEOUT",
|
|
1254
|
+
operation: "execute",
|
|
1255
|
+
message: `Request timeout after ${this.options.timeout || 3e4}ms`,
|
|
1256
|
+
statusCode: 408,
|
|
1257
|
+
logger: this.logger,
|
|
1258
|
+
metadata: {
|
|
1259
|
+
method: this.options.method,
|
|
1260
|
+
url
|
|
1261
|
+
},
|
|
1262
|
+
cause: error instanceof Error ? error : void 0
|
|
1263
|
+
});
|
|
1264
|
+
this.telemetry?.emit(
|
|
1265
|
+
"igniter.caller.request.timeout.error",
|
|
1266
|
+
{
|
|
1267
|
+
level: "error",
|
|
1268
|
+
attributes: {
|
|
1269
|
+
"ctx.request.method": method,
|
|
1270
|
+
"ctx.request.url": safeUrl,
|
|
1271
|
+
"ctx.request.timeoutMs": this.options.timeout || 3e4
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
this.logger?.error("IgniterCaller.request.execute timeout", {
|
|
1276
|
+
method,
|
|
1277
|
+
url: safeUrl,
|
|
1278
|
+
timeoutMs: this.options.timeout || 3e4,
|
|
1279
|
+
error: err
|
|
1280
|
+
});
|
|
1023
1281
|
return {
|
|
1024
1282
|
data: void 0,
|
|
1025
|
-
error:
|
|
1026
|
-
code: "IGNITER_CALLER_TIMEOUT",
|
|
1027
|
-
operation: "execute",
|
|
1028
|
-
message: `Request timeout after ${this.options.timeout || 3e4}ms`,
|
|
1029
|
-
statusCode: 408,
|
|
1030
|
-
logger: this.logger,
|
|
1031
|
-
metadata: {
|
|
1032
|
-
method: this.options.method,
|
|
1033
|
-
url
|
|
1034
|
-
},
|
|
1035
|
-
cause: error
|
|
1036
|
-
})
|
|
1283
|
+
error: err
|
|
1037
1284
|
};
|
|
1038
1285
|
}
|
|
1039
1286
|
return {
|
|
@@ -1048,13 +1295,13 @@ var IgniterCallerRequestBuilder = class {
|
|
|
1048
1295
|
method: this.options.method,
|
|
1049
1296
|
url
|
|
1050
1297
|
},
|
|
1051
|
-
cause: error
|
|
1298
|
+
cause: error instanceof Error ? error : void 0
|
|
1052
1299
|
})
|
|
1053
1300
|
};
|
|
1054
1301
|
}
|
|
1055
1302
|
}
|
|
1056
|
-
|
|
1057
|
-
const { method, url, body, params,
|
|
1303
|
+
resolveUrl() {
|
|
1304
|
+
const { method, url, body, params, baseURL } = this.options;
|
|
1058
1305
|
let finalParams = params;
|
|
1059
1306
|
if ((method === "GET" || method === "HEAD") && body && typeof body === "object") {
|
|
1060
1307
|
const bodyParams = {};
|
|
@@ -1070,6 +1317,14 @@ var IgniterCallerRequestBuilder = class {
|
|
|
1070
1317
|
baseURL,
|
|
1071
1318
|
query: finalParams
|
|
1072
1319
|
});
|
|
1320
|
+
return {
|
|
1321
|
+
url: fullUrl,
|
|
1322
|
+
safeUrl: fullUrl.split("?")[0]
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
buildRequest() {
|
|
1326
|
+
const { method, body, headers, timeout, cache } = this.options;
|
|
1327
|
+
const { url } = this.resolveUrl();
|
|
1073
1328
|
const shouldIncludeBody = body && method !== "GET" && method !== "HEAD";
|
|
1074
1329
|
const rawBody = shouldIncludeBody && IgniterCallerBodyUtils.isRawBody(body);
|
|
1075
1330
|
const finalHeaders = IgniterCallerBodyUtils.normalizeHeadersForBody(
|
|
@@ -1085,7 +1340,7 @@ var IgniterCallerRequestBuilder = class {
|
|
|
1085
1340
|
const controller = new AbortController();
|
|
1086
1341
|
const timeoutId = setTimeout(() => controller.abort(), timeout || 3e4);
|
|
1087
1342
|
return {
|
|
1088
|
-
url
|
|
1343
|
+
url,
|
|
1089
1344
|
requestInit,
|
|
1090
1345
|
controller,
|
|
1091
1346
|
timeoutId
|
|
@@ -1105,7 +1360,7 @@ var IgniterCallerRequestBuilder = class {
|
|
|
1105
1360
|
}
|
|
1106
1361
|
};
|
|
1107
1362
|
|
|
1108
|
-
// src/core/
|
|
1363
|
+
// src/core/events.ts
|
|
1109
1364
|
var IgniterCallerEvents = class {
|
|
1110
1365
|
constructor() {
|
|
1111
1366
|
this.listeners = /* @__PURE__ */ new Map();
|
|
@@ -1172,6 +1427,9 @@ var IgniterCallerEvents = class {
|
|
|
1172
1427
|
}
|
|
1173
1428
|
/**
|
|
1174
1429
|
* Removes a specific listener or all listeners for a pattern.
|
|
1430
|
+
*
|
|
1431
|
+
* @param pattern - URL string or RegExp pattern.
|
|
1432
|
+
* @param callback - Optional specific callback to remove.
|
|
1175
1433
|
*/
|
|
1176
1434
|
off(pattern, callback) {
|
|
1177
1435
|
if (typeof pattern === "string") {
|
|
@@ -1192,6 +1450,10 @@ var IgniterCallerEvents = class {
|
|
|
1192
1450
|
* Emits an event to all matching listeners.
|
|
1193
1451
|
*
|
|
1194
1452
|
* @internal
|
|
1453
|
+
*
|
|
1454
|
+
* @param url - Request URL to match listeners against.
|
|
1455
|
+
* @param method - HTTP method.
|
|
1456
|
+
* @param result - Response envelope.
|
|
1195
1457
|
*/
|
|
1196
1458
|
async emit(url, method, result) {
|
|
1197
1459
|
const context = {
|
|
@@ -1223,6 +1485,8 @@ var IgniterCallerEvents = class {
|
|
|
1223
1485
|
}
|
|
1224
1486
|
/**
|
|
1225
1487
|
* Removes all listeners.
|
|
1488
|
+
*
|
|
1489
|
+
* @returns Nothing.
|
|
1226
1490
|
*/
|
|
1227
1491
|
clear() {
|
|
1228
1492
|
this.listeners.clear();
|
|
@@ -1230,65 +1494,25 @@ var IgniterCallerEvents = class {
|
|
|
1230
1494
|
}
|
|
1231
1495
|
};
|
|
1232
1496
|
|
|
1233
|
-
// src/core/
|
|
1234
|
-
var
|
|
1497
|
+
// src/core/manager.ts
|
|
1498
|
+
var _IgniterCallerManager = class _IgniterCallerManager {
|
|
1499
|
+
/**
|
|
1500
|
+
* Creates a new manager instance.
|
|
1501
|
+
*
|
|
1502
|
+
* @param baseURL - Base URL prefix for requests.
|
|
1503
|
+
* @param opts - Optional configuration (headers, cookies, telemetry, schemas).
|
|
1504
|
+
*/
|
|
1235
1505
|
constructor(baseURL, opts) {
|
|
1236
1506
|
this.baseURL = baseURL;
|
|
1237
1507
|
this.headers = opts?.headers;
|
|
1238
1508
|
this.cookies = opts?.cookies;
|
|
1239
1509
|
this.logger = opts?.logger;
|
|
1510
|
+
this.telemetry = opts?.telemetry;
|
|
1240
1511
|
this.requestInterceptors = opts?.requestInterceptors;
|
|
1241
1512
|
this.responseInterceptors = opts?.responseInterceptors;
|
|
1242
1513
|
this.schemas = opts?.schemas;
|
|
1243
1514
|
this.schemaValidation = opts?.schemaValidation;
|
|
1244
1515
|
}
|
|
1245
|
-
/**
|
|
1246
|
-
* Canonical initialization entrypoint.
|
|
1247
|
-
*
|
|
1248
|
-
* This is designed to remain stable when extracted to `@igniter-js/caller`.
|
|
1249
|
-
*/
|
|
1250
|
-
static create() {
|
|
1251
|
-
return IgniterCallerBuilder.create((state) => {
|
|
1252
|
-
if (state.store) {
|
|
1253
|
-
IgniterCallerCacheUtils.setStore(state.store, state.storeOptions);
|
|
1254
|
-
}
|
|
1255
|
-
return new _IgniterCaller(state.baseURL, {
|
|
1256
|
-
headers: state.headers,
|
|
1257
|
-
cookies: state.cookies,
|
|
1258
|
-
logger: state.logger,
|
|
1259
|
-
requestInterceptors: state.requestInterceptors,
|
|
1260
|
-
responseInterceptors: state.responseInterceptors,
|
|
1261
|
-
schemas: state.schemas,
|
|
1262
|
-
schemaValidation: state.schemaValidation
|
|
1263
|
-
});
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
/**
|
|
1267
|
-
* Returns a new client with the same config and a new logger.
|
|
1268
|
-
*/
|
|
1269
|
-
withLogger(logger) {
|
|
1270
|
-
return new _IgniterCaller(this.baseURL, {
|
|
1271
|
-
headers: this.headers,
|
|
1272
|
-
cookies: this.cookies,
|
|
1273
|
-
logger,
|
|
1274
|
-
requestInterceptors: this.requestInterceptors,
|
|
1275
|
-
responseInterceptors: this.responseInterceptors,
|
|
1276
|
-
schemas: this.schemas,
|
|
1277
|
-
schemaValidation: this.schemaValidation
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
setBaseURL(baseURL) {
|
|
1281
|
-
this.baseURL = baseURL;
|
|
1282
|
-
return this;
|
|
1283
|
-
}
|
|
1284
|
-
setHeaders(headers) {
|
|
1285
|
-
this.headers = headers;
|
|
1286
|
-
return this;
|
|
1287
|
-
}
|
|
1288
|
-
setCookies(cookies) {
|
|
1289
|
-
this.cookies = cookies;
|
|
1290
|
-
return this;
|
|
1291
|
-
}
|
|
1292
1516
|
/**
|
|
1293
1517
|
* Creates common request builder params.
|
|
1294
1518
|
*/
|
|
@@ -1298,126 +1522,46 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1298
1522
|
defaultHeaders: this.headers,
|
|
1299
1523
|
defaultCookies: this.cookies,
|
|
1300
1524
|
logger: this.logger,
|
|
1525
|
+
telemetry: this.telemetry,
|
|
1301
1526
|
requestInterceptors: this.requestInterceptors,
|
|
1302
1527
|
responseInterceptors: this.responseInterceptors,
|
|
1303
1528
|
eventEmitter: async (url, method, result) => {
|
|
1304
|
-
await
|
|
1529
|
+
await _IgniterCallerManager.emitEvent(url, method, result);
|
|
1305
1530
|
},
|
|
1306
1531
|
schemas: this.schemas,
|
|
1307
1532
|
schemaValidation: this.schemaValidation
|
|
1308
1533
|
};
|
|
1309
1534
|
}
|
|
1310
|
-
/**
|
|
1311
|
-
* Resolves the full URL path by prepending baseURL if needed.
|
|
1312
|
-
*/
|
|
1313
|
-
resolveSchemaPath(url) {
|
|
1314
|
-
if (this.baseURL && !url.startsWith("http")) {
|
|
1315
|
-
return `${this.baseURL}${url}`;
|
|
1316
|
-
}
|
|
1317
|
-
return url;
|
|
1318
|
-
}
|
|
1319
|
-
/**
|
|
1320
|
-
* Creates a GET request.
|
|
1321
|
-
*
|
|
1322
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1323
|
-
*
|
|
1324
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1325
|
-
*
|
|
1326
|
-
* @example
|
|
1327
|
-
* ```ts
|
|
1328
|
-
* // With typed schema - response type is inferred
|
|
1329
|
-
* const result = await api.get('/users').execute()
|
|
1330
|
-
* // result.data is typed based on schema
|
|
1331
|
-
*
|
|
1332
|
-
* // Without schema or URL set later
|
|
1333
|
-
* const result = await api.get().url('/users').execute()
|
|
1334
|
-
* ```
|
|
1335
|
-
*/
|
|
1336
1535
|
get(url) {
|
|
1337
1536
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1338
1537
|
builder._setMethod("GET");
|
|
1339
1538
|
if (url) builder._setUrl(url);
|
|
1340
1539
|
return builder;
|
|
1341
1540
|
}
|
|
1342
|
-
/**
|
|
1343
|
-
* Creates a POST request.
|
|
1344
|
-
*
|
|
1345
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1346
|
-
*
|
|
1347
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1348
|
-
*
|
|
1349
|
-
* @example
|
|
1350
|
-
* ```ts
|
|
1351
|
-
* const result = await api.post('/users').body({ name: 'John' }).execute()
|
|
1352
|
-
* ```
|
|
1353
|
-
*/
|
|
1354
1541
|
post(url) {
|
|
1355
1542
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1356
1543
|
builder._setMethod("POST");
|
|
1357
1544
|
if (url) builder._setUrl(url);
|
|
1358
1545
|
return builder;
|
|
1359
1546
|
}
|
|
1360
|
-
/**
|
|
1361
|
-
* Creates a PUT request.
|
|
1362
|
-
*
|
|
1363
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1364
|
-
*
|
|
1365
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1366
|
-
*
|
|
1367
|
-
* @example
|
|
1368
|
-
* ```ts
|
|
1369
|
-
* const result = await api.put('/users/1').body({ name: 'Jane' }).execute()
|
|
1370
|
-
* ```
|
|
1371
|
-
*/
|
|
1372
1547
|
put(url) {
|
|
1373
1548
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1374
1549
|
builder._setMethod("PUT");
|
|
1375
1550
|
if (url) builder._setUrl(url);
|
|
1376
1551
|
return builder;
|
|
1377
1552
|
}
|
|
1378
|
-
/**
|
|
1379
|
-
* Creates a PATCH request.
|
|
1380
|
-
*
|
|
1381
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1382
|
-
*
|
|
1383
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1384
|
-
*
|
|
1385
|
-
* @example
|
|
1386
|
-
* ```ts
|
|
1387
|
-
* const result = await api.patch('/users/1').body({ name: 'Jane' }).execute()
|
|
1388
|
-
* ```
|
|
1389
|
-
*/
|
|
1390
1553
|
patch(url) {
|
|
1391
1554
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1392
1555
|
builder._setMethod("PATCH");
|
|
1393
1556
|
if (url) builder._setUrl(url);
|
|
1394
1557
|
return builder;
|
|
1395
1558
|
}
|
|
1396
|
-
/**
|
|
1397
|
-
* Creates a DELETE request.
|
|
1398
|
-
*
|
|
1399
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1400
|
-
*
|
|
1401
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1402
|
-
*
|
|
1403
|
-
* @example
|
|
1404
|
-
* ```ts
|
|
1405
|
-
* const result = await api.delete('/users/1').execute()
|
|
1406
|
-
* ```
|
|
1407
|
-
*/
|
|
1408
1559
|
delete(url) {
|
|
1409
1560
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1410
1561
|
builder._setMethod("DELETE");
|
|
1411
1562
|
if (url) builder._setUrl(url);
|
|
1412
1563
|
return builder;
|
|
1413
1564
|
}
|
|
1414
|
-
/**
|
|
1415
|
-
* Creates a HEAD request.
|
|
1416
|
-
*
|
|
1417
|
-
* When a URL is provided and matches a schema, the response type is automatically inferred.
|
|
1418
|
-
*
|
|
1419
|
-
* @param url Optional URL for the request. Can also be set via `.url()`.
|
|
1420
|
-
*/
|
|
1421
1565
|
head(url) {
|
|
1422
1566
|
const builder = new IgniterCallerRequestBuilder(this.createBuilderParams());
|
|
1423
1567
|
builder._setMethod("HEAD");
|
|
@@ -1430,6 +1574,9 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1430
1574
|
* This is a convenience method for making requests without using the builder pattern.
|
|
1431
1575
|
* Useful for dynamic requests where options are constructed programmatically.
|
|
1432
1576
|
*
|
|
1577
|
+
* @param options - Request configuration for method, url, and behavior.
|
|
1578
|
+
* @returns Response envelope with data or error.
|
|
1579
|
+
*
|
|
1433
1580
|
* @example
|
|
1434
1581
|
* ```ts
|
|
1435
1582
|
* const result = await api.request({
|
|
@@ -1496,6 +1643,9 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1496
1643
|
* Executes multiple requests in parallel and returns results as an array.
|
|
1497
1644
|
*
|
|
1498
1645
|
* This is useful for batching independent API calls.
|
|
1646
|
+
*
|
|
1647
|
+
* @param requests - Array of request promises.
|
|
1648
|
+
* @returns Array of resolved results in the same order.
|
|
1499
1649
|
*/
|
|
1500
1650
|
static async batch(requests) {
|
|
1501
1651
|
return Promise.all(requests);
|
|
@@ -1516,7 +1666,7 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1516
1666
|
* @example
|
|
1517
1667
|
* ```ts
|
|
1518
1668
|
* // Listen to all user endpoints
|
|
1519
|
-
* const cleanup =
|
|
1669
|
+
* const cleanup = IgniterCallerManager.on(/^\/users/, (result, context) => {
|
|
1520
1670
|
* console.log(`${context.method} ${context.url}`, result)
|
|
1521
1671
|
* })
|
|
1522
1672
|
*
|
|
@@ -1525,24 +1675,29 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1525
1675
|
* ```
|
|
1526
1676
|
*/
|
|
1527
1677
|
static on(pattern, callback) {
|
|
1528
|
-
return
|
|
1678
|
+
return _IgniterCallerManager.events.on(pattern, callback);
|
|
1529
1679
|
}
|
|
1530
1680
|
/**
|
|
1531
1681
|
* Removes event listeners for a pattern.
|
|
1682
|
+
*
|
|
1683
|
+
* @param pattern - URL string or RegExp pattern.
|
|
1684
|
+
* @param callback - Callback to remove (optional).
|
|
1532
1685
|
*/
|
|
1533
1686
|
static off(pattern, callback) {
|
|
1534
|
-
|
|
1687
|
+
_IgniterCallerManager.events.off(pattern, callback);
|
|
1535
1688
|
}
|
|
1536
1689
|
/**
|
|
1537
1690
|
* Invalidates a specific cache entry.
|
|
1538
1691
|
*
|
|
1539
1692
|
* This is useful after mutations to ensure fresh data on next fetch.
|
|
1540
1693
|
*
|
|
1694
|
+
* @param key - Cache key to invalidate.
|
|
1695
|
+
*
|
|
1541
1696
|
* @example
|
|
1542
1697
|
* ```ts
|
|
1543
1698
|
* // After creating a user
|
|
1544
1699
|
* await api.post('/users').body(newUser).execute()
|
|
1545
|
-
* await
|
|
1700
|
+
* await IgniterCallerManager.invalidate('/users') // Clear users list cache
|
|
1546
1701
|
* ```
|
|
1547
1702
|
*/
|
|
1548
1703
|
static async invalidate(key) {
|
|
@@ -1552,11 +1707,12 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1552
1707
|
* Invalidates all cache entries matching a pattern.
|
|
1553
1708
|
*
|
|
1554
1709
|
* @param pattern Glob pattern (e.g., '/users/*') or exact key
|
|
1710
|
+
* @returns Promise that resolves when invalidation completes.
|
|
1555
1711
|
*
|
|
1556
1712
|
* @example
|
|
1557
1713
|
* ```ts
|
|
1558
1714
|
* // Invalidate all user-related caches
|
|
1559
|
-
* await
|
|
1715
|
+
* await IgniterCallerManager.invalidatePattern('/users/*')
|
|
1560
1716
|
* ```
|
|
1561
1717
|
*/
|
|
1562
1718
|
static async invalidatePattern(pattern) {
|
|
@@ -1566,25 +1722,539 @@ var _IgniterCaller = class _IgniterCaller {
|
|
|
1566
1722
|
* Emits an event to all registered listeners.
|
|
1567
1723
|
*
|
|
1568
1724
|
* @internal
|
|
1725
|
+
*
|
|
1726
|
+
* @param url - Request URL (resolved).
|
|
1727
|
+
* @param method - HTTP method.
|
|
1728
|
+
* @param result - Response envelope.
|
|
1569
1729
|
*/
|
|
1570
1730
|
static async emitEvent(url, method, result) {
|
|
1571
|
-
await
|
|
1731
|
+
await _IgniterCallerManager.events.emit(url, method, result);
|
|
1572
1732
|
}
|
|
1573
1733
|
};
|
|
1574
1734
|
/** Global event emitter for observing HTTP responses */
|
|
1575
|
-
|
|
1576
|
-
var
|
|
1735
|
+
_IgniterCallerManager.events = new IgniterCallerEvents();
|
|
1736
|
+
var IgniterCallerManager = _IgniterCallerManager;
|
|
1737
|
+
|
|
1738
|
+
// src/builders/main.builder.ts
|
|
1739
|
+
var IgniterCallerBuilder = class _IgniterCallerBuilder {
|
|
1740
|
+
constructor(state) {
|
|
1741
|
+
this.state = state;
|
|
1742
|
+
}
|
|
1743
|
+
/**
|
|
1744
|
+
* Creates a new builder instance.
|
|
1745
|
+
*
|
|
1746
|
+
* @returns New builder instance with empty state.
|
|
1747
|
+
*/
|
|
1748
|
+
static create() {
|
|
1749
|
+
return new _IgniterCallerBuilder({});
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Sets the base URL for all requests.
|
|
1753
|
+
*
|
|
1754
|
+
* @param baseURL - Base URL prefix for outgoing requests.
|
|
1755
|
+
*/
|
|
1756
|
+
withBaseUrl(baseURL) {
|
|
1757
|
+
return new _IgniterCallerBuilder({ ...this.state, baseURL });
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Merges default headers for all requests.
|
|
1761
|
+
*
|
|
1762
|
+
* @param headers - Header map merged into every request.
|
|
1763
|
+
*/
|
|
1764
|
+
withHeaders(headers) {
|
|
1765
|
+
return new _IgniterCallerBuilder({ ...this.state, headers });
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* Sets default cookies (sent as the `Cookie` header).
|
|
1769
|
+
*
|
|
1770
|
+
* @param cookies - Cookie key/value pairs.
|
|
1771
|
+
*/
|
|
1772
|
+
withCookies(cookies) {
|
|
1773
|
+
return new _IgniterCallerBuilder({ ...this.state, cookies });
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Attaches a logger instance.
|
|
1777
|
+
*
|
|
1778
|
+
* @param logger - Logger implementation from `@igniter-js/core`.
|
|
1779
|
+
*/
|
|
1780
|
+
withLogger(logger) {
|
|
1781
|
+
return new _IgniterCallerBuilder({ ...this.state, logger });
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Adds a request interceptor that runs before each request.
|
|
1785
|
+
*
|
|
1786
|
+
* @param interceptor - Interceptor called with request options.
|
|
1787
|
+
*/
|
|
1788
|
+
withRequestInterceptor(interceptor) {
|
|
1789
|
+
const requestInterceptors = [
|
|
1790
|
+
...this.state.requestInterceptors || [],
|
|
1791
|
+
interceptor
|
|
1792
|
+
];
|
|
1793
|
+
return new _IgniterCallerBuilder({ ...this.state, requestInterceptors });
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* Adds a response interceptor that runs after each request.
|
|
1797
|
+
*
|
|
1798
|
+
* @param interceptor - Interceptor called with the response result.
|
|
1799
|
+
*/
|
|
1800
|
+
withResponseInterceptor(interceptor) {
|
|
1801
|
+
const responseInterceptors = [
|
|
1802
|
+
...this.state.responseInterceptors || [],
|
|
1803
|
+
interceptor
|
|
1804
|
+
];
|
|
1805
|
+
return new _IgniterCallerBuilder({ ...this.state, responseInterceptors });
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Configures a persistent store adapter for caching.
|
|
1809
|
+
*
|
|
1810
|
+
* When configured, cache operations will use the store (e.g., Redis)
|
|
1811
|
+
* instead of in-memory cache, enabling persistent cache across deployments.
|
|
1812
|
+
*
|
|
1813
|
+
* @param store - Store adapter implementation.
|
|
1814
|
+
* @param options - Store options (ttl, keyPrefix, fallback).
|
|
1815
|
+
*/
|
|
1816
|
+
withStore(store, options) {
|
|
1817
|
+
return new _IgniterCallerBuilder({
|
|
1818
|
+
...this.state,
|
|
1819
|
+
store,
|
|
1820
|
+
storeOptions: options
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Configures schema-based type safety and validation.
|
|
1825
|
+
*
|
|
1826
|
+
* Enables automatic type inference for requests/responses based on
|
|
1827
|
+
* route and method, with optional runtime validation via StandardSchemaV1
|
|
1828
|
+
* (Zod is supported).
|
|
1829
|
+
*
|
|
1830
|
+
* @param schemas - Schema map keyed by URL path and method.
|
|
1831
|
+
* @param validation - Validation options for request/response checks.
|
|
1832
|
+
*
|
|
1833
|
+
* @example
|
|
1834
|
+
* ```ts
|
|
1835
|
+
* const api = IgniterCaller.create()
|
|
1836
|
+
* .withSchemas({
|
|
1837
|
+
* '/users': {
|
|
1838
|
+
* GET: {
|
|
1839
|
+
* responses: {
|
|
1840
|
+
* 200: z.array(UserSchema),
|
|
1841
|
+
* 401: ErrorSchema,
|
|
1842
|
+
* },
|
|
1843
|
+
* },
|
|
1844
|
+
* POST: {
|
|
1845
|
+
* request: CreateUserSchema,
|
|
1846
|
+
* responses: {
|
|
1847
|
+
* 201: UserSchema,
|
|
1848
|
+
* 400: ValidationErrorSchema,
|
|
1849
|
+
* },
|
|
1850
|
+
* },
|
|
1851
|
+
* },
|
|
1852
|
+
* })
|
|
1853
|
+
* .build()
|
|
1854
|
+
* ```
|
|
1855
|
+
*/
|
|
1856
|
+
withSchemas(schemas, validation) {
|
|
1857
|
+
const nextState = {
|
|
1858
|
+
...this.state,
|
|
1859
|
+
schemas,
|
|
1860
|
+
schemaValidation: validation
|
|
1861
|
+
};
|
|
1862
|
+
return new _IgniterCallerBuilder(nextState);
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Attaches telemetry for request monitoring and observability.
|
|
1866
|
+
*
|
|
1867
|
+
* Telemetry is optional and only emits events when a manager is provided.
|
|
1868
|
+
*
|
|
1869
|
+
* Telemetry events emitted by the caller package include:
|
|
1870
|
+
* - `request.execute.started`
|
|
1871
|
+
* - `request.execute.success`
|
|
1872
|
+
* - `request.execute.error`
|
|
1873
|
+
* - `request.timeout.error`
|
|
1874
|
+
* - `cache.read.hit`
|
|
1875
|
+
* - `retry.attempt.started`
|
|
1876
|
+
* - `validation.request.error`
|
|
1877
|
+
* - `validation.response.error`
|
|
1878
|
+
*
|
|
1879
|
+
* @param telemetry - Telemetry manager instance.
|
|
1880
|
+
*
|
|
1881
|
+
* @example
|
|
1882
|
+
* ```ts
|
|
1883
|
+
* import { IgniterTelemetry } from '@igniter-js/telemetry'
|
|
1884
|
+
* import { IgniterCallerTelemetryEvents } from '@igniter-js/caller/telemetry'
|
|
1885
|
+
*
|
|
1886
|
+
* const telemetry = IgniterTelemetry.create()
|
|
1887
|
+
* .withService('my-api')
|
|
1888
|
+
* .addEvents(IgniterCallerTelemetryEvents)
|
|
1889
|
+
* .build()
|
|
1890
|
+
*
|
|
1891
|
+
* const api = IgniterCaller.create()
|
|
1892
|
+
* .withBaseUrl('https://api.example.com')
|
|
1893
|
+
* .withTelemetry(telemetry)
|
|
1894
|
+
* .build()
|
|
1895
|
+
* ```
|
|
1896
|
+
*/
|
|
1897
|
+
withTelemetry(telemetry) {
|
|
1898
|
+
return new _IgniterCallerBuilder({ ...this.state, telemetry });
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Builds the `IgniterCaller` instance.
|
|
1902
|
+
*
|
|
1903
|
+
* @returns Configured manager instance.
|
|
1904
|
+
*/
|
|
1905
|
+
build() {
|
|
1906
|
+
if (this.state.store) {
|
|
1907
|
+
IgniterCallerCacheUtils.setStore(this.state.store, this.state.storeOptions);
|
|
1908
|
+
}
|
|
1909
|
+
const manager = new IgniterCallerManager(this.state.baseURL, {
|
|
1910
|
+
headers: this.state.headers,
|
|
1911
|
+
cookies: this.state.cookies,
|
|
1912
|
+
logger: this.state.logger,
|
|
1913
|
+
telemetry: this.state.telemetry,
|
|
1914
|
+
requestInterceptors: this.state.requestInterceptors,
|
|
1915
|
+
responseInterceptors: this.state.responseInterceptors,
|
|
1916
|
+
schemas: this.state.schemas,
|
|
1917
|
+
schemaValidation: this.state.schemaValidation
|
|
1918
|
+
});
|
|
1919
|
+
this.state.logger?.info("IgniterCaller initialized", {
|
|
1920
|
+
baseURL: this.state.baseURL,
|
|
1921
|
+
hasTelemetry: Boolean(this.state.telemetry),
|
|
1922
|
+
hasStore: Boolean(this.state.store),
|
|
1923
|
+
hasSchemas: Boolean(this.state.schemas)
|
|
1924
|
+
});
|
|
1925
|
+
return manager;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
var IgniterCaller = {
|
|
1929
|
+
create: IgniterCallerBuilder.create
|
|
1930
|
+
};
|
|
1931
|
+
var IgniterCallerSchemaPathBuilder = class _IgniterCallerSchemaPathBuilder {
|
|
1932
|
+
constructor(methods, registry) {
|
|
1933
|
+
this.methods = methods;
|
|
1934
|
+
this.registry = registry;
|
|
1935
|
+
}
|
|
1936
|
+
/**
|
|
1937
|
+
* Creates a new path builder for the provided registry.
|
|
1938
|
+
*/
|
|
1939
|
+
static create(registry) {
|
|
1940
|
+
return new _IgniterCallerSchemaPathBuilder({}, registry);
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Returns a registry reference helper for a given key.
|
|
1944
|
+
* The helper exposes optional Zod-based wrappers (array/optional/nullable/record).
|
|
1945
|
+
*/
|
|
1946
|
+
ref(key) {
|
|
1947
|
+
const schema = this.registry[key];
|
|
1948
|
+
const zodSchema = schema;
|
|
1949
|
+
return {
|
|
1950
|
+
schema,
|
|
1951
|
+
array: () => zod.z.array(zodSchema),
|
|
1952
|
+
nullable: () => zodSchema.nullable(),
|
|
1953
|
+
optional: () => zodSchema.optional(),
|
|
1954
|
+
record: (keyType) => zod.z.record(
|
|
1955
|
+
zod.z.any(),
|
|
1956
|
+
zodSchema
|
|
1957
|
+
)
|
|
1958
|
+
};
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Defines a GET endpoint.
|
|
1962
|
+
*/
|
|
1963
|
+
get(config) {
|
|
1964
|
+
return this.addMethod("GET", config);
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Defines a POST endpoint.
|
|
1968
|
+
*/
|
|
1969
|
+
post(config) {
|
|
1970
|
+
return this.addMethod("POST", config);
|
|
1971
|
+
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Defines a PUT endpoint.
|
|
1974
|
+
*/
|
|
1975
|
+
put(config) {
|
|
1976
|
+
return this.addMethod("PUT", config);
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Defines a PATCH endpoint.
|
|
1980
|
+
*/
|
|
1981
|
+
patch(config) {
|
|
1982
|
+
return this.addMethod("PATCH", config);
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Defines a DELETE endpoint.
|
|
1986
|
+
*/
|
|
1987
|
+
delete(config) {
|
|
1988
|
+
return this.addMethod("DELETE", config);
|
|
1989
|
+
}
|
|
1990
|
+
/**
|
|
1991
|
+
* Defines a HEAD endpoint.
|
|
1992
|
+
*/
|
|
1993
|
+
head(config) {
|
|
1994
|
+
return this.addMethod("HEAD", config);
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Builds the accumulated method map for the path.
|
|
1998
|
+
*/
|
|
1999
|
+
build() {
|
|
2000
|
+
return this.methods;
|
|
2001
|
+
}
|
|
2002
|
+
addMethod(method, config) {
|
|
2003
|
+
if (method in this.methods) {
|
|
2004
|
+
throw new IgniterCallerError({
|
|
2005
|
+
code: "IGNITER_CALLER_SCHEMA_DUPLICATE",
|
|
2006
|
+
operation: "buildSchema",
|
|
2007
|
+
message: `Schema for method "${method}" is already defined on this path.`,
|
|
2008
|
+
statusCode: 400,
|
|
2009
|
+
metadata: { method }
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
return new _IgniterCallerSchemaPathBuilder(
|
|
2013
|
+
{
|
|
2014
|
+
...this.methods,
|
|
2015
|
+
[method]: {
|
|
2016
|
+
...config
|
|
2017
|
+
}
|
|
2018
|
+
},
|
|
2019
|
+
this.registry
|
|
2020
|
+
);
|
|
2021
|
+
}
|
|
2022
|
+
};
|
|
2023
|
+
|
|
2024
|
+
// src/builders/schema.builder.ts
|
|
2025
|
+
var IgniterCallerSchema = class _IgniterCallerSchema {
|
|
2026
|
+
constructor(schemas, registry) {
|
|
2027
|
+
this.schemas = schemas;
|
|
2028
|
+
this.registry = registry;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Creates a new empty schema builder.
|
|
2032
|
+
*/
|
|
2033
|
+
static create() {
|
|
2034
|
+
return new _IgniterCallerSchema({}, {});
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* Registers a reusable schema in the registry.
|
|
2038
|
+
*/
|
|
2039
|
+
schema(key, schema, options) {
|
|
2040
|
+
ensureValidSchemaKey(key);
|
|
2041
|
+
if (key in this.registry) {
|
|
2042
|
+
throw new IgniterCallerError({
|
|
2043
|
+
code: "IGNITER_CALLER_SCHEMA_DUPLICATE",
|
|
2044
|
+
operation: "buildSchema",
|
|
2045
|
+
message: `Schema registry key "${key}" is already defined.`,
|
|
2046
|
+
statusCode: 400,
|
|
2047
|
+
metadata: { key }
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
const nextRegistry = {
|
|
2051
|
+
...this.registry,
|
|
2052
|
+
[key]: schema
|
|
2053
|
+
};
|
|
2054
|
+
void options?.internal;
|
|
2055
|
+
return new _IgniterCallerSchema(this.schemas, nextRegistry);
|
|
2056
|
+
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Defines a path with its methods using a fluent builder.
|
|
2059
|
+
*/
|
|
2060
|
+
path(path, builder) {
|
|
2061
|
+
ensureValidPath(path);
|
|
2062
|
+
const pathBuilder = IgniterCallerSchemaPathBuilder.create(this.registry);
|
|
2063
|
+
const builtMethods = builder(pathBuilder).build();
|
|
2064
|
+
const existing = this.schemas[path] ?? {};
|
|
2065
|
+
for (const method of Object.keys(
|
|
2066
|
+
builtMethods
|
|
2067
|
+
)) {
|
|
2068
|
+
if (method in existing) {
|
|
2069
|
+
throw new IgniterCallerError({
|
|
2070
|
+
code: "IGNITER_CALLER_SCHEMA_DUPLICATE",
|
|
2071
|
+
operation: "buildSchema",
|
|
2072
|
+
message: `Schema for "${path}" with method "${method}" is already defined.`,
|
|
2073
|
+
statusCode: 400,
|
|
2074
|
+
metadata: { path, method }
|
|
2075
|
+
});
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
const merged = {
|
|
2079
|
+
...existing,
|
|
2080
|
+
...builtMethods
|
|
2081
|
+
};
|
|
2082
|
+
const nextSchemas = {
|
|
2083
|
+
...this.schemas,
|
|
2084
|
+
[path]: merged
|
|
2085
|
+
};
|
|
2086
|
+
return new _IgniterCallerSchema(nextSchemas, this.registry);
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Builds the schema map and attaches inference + runtime helpers.
|
|
2090
|
+
*/
|
|
2091
|
+
build() {
|
|
2092
|
+
const result = {
|
|
2093
|
+
...this.schemas
|
|
2094
|
+
};
|
|
2095
|
+
const inferHelpers = createInferHelpers();
|
|
2096
|
+
const getHelpers = createGetHelpers(this.schemas, this.registry);
|
|
2097
|
+
Object.defineProperty(result, "$Infer", {
|
|
2098
|
+
value: inferHelpers,
|
|
2099
|
+
enumerable: false
|
|
2100
|
+
});
|
|
2101
|
+
Object.defineProperty(result, "get", {
|
|
2102
|
+
value: getHelpers,
|
|
2103
|
+
enumerable: false
|
|
2104
|
+
});
|
|
2105
|
+
return result;
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
function createInferHelpers() {
|
|
2109
|
+
return {
|
|
2110
|
+
Path: void 0,
|
|
2111
|
+
Endpoint: (() => void 0),
|
|
2112
|
+
Request: (() => void 0),
|
|
2113
|
+
Response: (() => void 0),
|
|
2114
|
+
Responses: (() => void 0),
|
|
2115
|
+
Schema: (() => void 0)
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
function createGetHelpers(schemas, registry) {
|
|
2119
|
+
return {
|
|
2120
|
+
path: (path) => schemas[path],
|
|
2121
|
+
endpoint: (path, method) => schemas[path][method],
|
|
2122
|
+
request: (path, method) => schemas[path][method]?.request,
|
|
2123
|
+
response: (path, method, status) => schemas[path][method]?.responses?.[status],
|
|
2124
|
+
schema: (key) => registry[key]
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2127
|
+
function ensureValidPath(path) {
|
|
2128
|
+
if (!path || path.trim().length === 0) {
|
|
2129
|
+
throw new IgniterCallerError({
|
|
2130
|
+
code: "IGNITER_CALLER_SCHEMA_INVALID",
|
|
2131
|
+
operation: "buildSchema",
|
|
2132
|
+
message: "Path cannot be empty.",
|
|
2133
|
+
statusCode: 400
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
if (!path.startsWith("/")) {
|
|
2137
|
+
throw new IgniterCallerError({
|
|
2138
|
+
code: "IGNITER_CALLER_SCHEMA_INVALID",
|
|
2139
|
+
operation: "buildSchema",
|
|
2140
|
+
message: `Path "${path}" must start with "/".`,
|
|
2141
|
+
statusCode: 400,
|
|
2142
|
+
metadata: { path }
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
function ensureValidSchemaKey(key) {
|
|
2147
|
+
if (!key || key.trim().length === 0) {
|
|
2148
|
+
throw new IgniterCallerError({
|
|
2149
|
+
code: "IGNITER_CALLER_SCHEMA_INVALID",
|
|
2150
|
+
operation: "buildSchema",
|
|
2151
|
+
message: "Schema registry key cannot be empty.",
|
|
2152
|
+
statusCode: 400
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
// src/adapters/mock.adapter.ts
|
|
2158
|
+
var MockCallerStoreAdapter = class _MockCallerStoreAdapter {
|
|
2159
|
+
constructor() {
|
|
2160
|
+
/** Underlying in-memory store. */
|
|
2161
|
+
this.client = /* @__PURE__ */ new Map();
|
|
2162
|
+
/** Tracks all calls for assertions. */
|
|
2163
|
+
this.calls = {
|
|
2164
|
+
get: 0,
|
|
2165
|
+
set: 0,
|
|
2166
|
+
delete: 0,
|
|
2167
|
+
has: 0
|
|
2168
|
+
};
|
|
2169
|
+
/** Captures recent operations. */
|
|
2170
|
+
this.history = {
|
|
2171
|
+
get: [],
|
|
2172
|
+
set: [],
|
|
2173
|
+
delete: [],
|
|
2174
|
+
has: []
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
/** Creates a new mock adapter instance. */
|
|
2178
|
+
static create() {
|
|
2179
|
+
return new _MockCallerStoreAdapter();
|
|
2180
|
+
}
|
|
2181
|
+
/**
|
|
2182
|
+
* Retrieves a cached value by key.
|
|
2183
|
+
*
|
|
2184
|
+
* @param key - Cache key (without prefix).
|
|
2185
|
+
* @returns Cached value or null.
|
|
2186
|
+
*/
|
|
2187
|
+
async get(key) {
|
|
2188
|
+
this.calls.get += 1;
|
|
2189
|
+
this.history.get.push(key);
|
|
2190
|
+
return this.client.has(key) ? this.client.get(key) : null;
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Stores a cached value.
|
|
2194
|
+
*
|
|
2195
|
+
* @param key - Cache key (without prefix).
|
|
2196
|
+
* @param value - Value to store.
|
|
2197
|
+
* @param options - Cache options (ttl, etc).
|
|
2198
|
+
*/
|
|
2199
|
+
async set(key, value, options) {
|
|
2200
|
+
this.calls.set += 1;
|
|
2201
|
+
this.history.set.push({ key, value, options });
|
|
2202
|
+
this.client.set(key, value);
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Removes a cached value.
|
|
2206
|
+
*
|
|
2207
|
+
* @param key - Cache key (without prefix).
|
|
2208
|
+
*/
|
|
2209
|
+
async delete(key) {
|
|
2210
|
+
this.calls.delete += 1;
|
|
2211
|
+
this.history.delete.push(key);
|
|
2212
|
+
this.client.delete(key);
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* Checks if a cached value exists.
|
|
2216
|
+
*
|
|
2217
|
+
* @param key - Cache key (without prefix).
|
|
2218
|
+
* @returns True when the key exists.
|
|
2219
|
+
*/
|
|
2220
|
+
async has(key) {
|
|
2221
|
+
this.calls.has += 1;
|
|
2222
|
+
this.history.has.push(key);
|
|
2223
|
+
return this.client.has(key);
|
|
2224
|
+
}
|
|
2225
|
+
/**
|
|
2226
|
+
* Clears all tracked state.
|
|
2227
|
+
*
|
|
2228
|
+
* @returns Nothing.
|
|
2229
|
+
*/
|
|
2230
|
+
clear() {
|
|
2231
|
+
this.client.clear();
|
|
2232
|
+
this.calls.get = 0;
|
|
2233
|
+
this.calls.set = 0;
|
|
2234
|
+
this.calls.delete = 0;
|
|
2235
|
+
this.calls.has = 0;
|
|
2236
|
+
this.history.get = [];
|
|
2237
|
+
this.history.set = [];
|
|
2238
|
+
this.history.delete = [];
|
|
2239
|
+
this.history.has = [];
|
|
2240
|
+
}
|
|
2241
|
+
};
|
|
1577
2242
|
|
|
1578
2243
|
// src/utils/testing.ts
|
|
1579
2244
|
var IgniterCallerMock = class {
|
|
1580
2245
|
/**
|
|
1581
2246
|
* Creates a successful mock response.
|
|
2247
|
+
*
|
|
2248
|
+
* @param data - Mock response data.
|
|
1582
2249
|
*/
|
|
1583
2250
|
static mockResponse(data) {
|
|
1584
2251
|
return { data, error: void 0 };
|
|
1585
2252
|
}
|
|
1586
2253
|
/**
|
|
1587
2254
|
* Creates an error mock response.
|
|
2255
|
+
*
|
|
2256
|
+
* @param code - Error code to use.
|
|
2257
|
+
* @param message - Optional error message.
|
|
1588
2258
|
*/
|
|
1589
2259
|
static mockError(code, message = "Mock error") {
|
|
1590
2260
|
return {
|
|
@@ -1598,6 +2268,9 @@ var IgniterCallerMock = class {
|
|
|
1598
2268
|
}
|
|
1599
2269
|
/**
|
|
1600
2270
|
* Creates a successful file download mock.
|
|
2271
|
+
*
|
|
2272
|
+
* @param filename - File name for the mock.
|
|
2273
|
+
* @param content - File contents as string or Blob.
|
|
1601
2274
|
*/
|
|
1602
2275
|
static mockFile(filename, content) {
|
|
1603
2276
|
const blob = typeof content === "string" ? new Blob([content]) : content;
|
|
@@ -1606,6 +2279,8 @@ var IgniterCallerMock = class {
|
|
|
1606
2279
|
}
|
|
1607
2280
|
/**
|
|
1608
2281
|
* Creates a failed file download mock.
|
|
2282
|
+
*
|
|
2283
|
+
* @param message - Optional error message.
|
|
1609
2284
|
*/
|
|
1610
2285
|
static mockFileError(message = "Mock file error") {
|
|
1611
2286
|
return {
|
|
@@ -1625,9 +2300,13 @@ exports.IgniterCallerBuilder = IgniterCallerBuilder;
|
|
|
1625
2300
|
exports.IgniterCallerCacheUtils = IgniterCallerCacheUtils;
|
|
1626
2301
|
exports.IgniterCallerError = IgniterCallerError;
|
|
1627
2302
|
exports.IgniterCallerEvents = IgniterCallerEvents;
|
|
2303
|
+
exports.IgniterCallerManager = IgniterCallerManager;
|
|
1628
2304
|
exports.IgniterCallerMock = IgniterCallerMock;
|
|
1629
2305
|
exports.IgniterCallerRequestBuilder = IgniterCallerRequestBuilder;
|
|
2306
|
+
exports.IgniterCallerSchema = IgniterCallerSchema;
|
|
2307
|
+
exports.IgniterCallerSchemaPathBuilder = IgniterCallerSchemaPathBuilder;
|
|
1630
2308
|
exports.IgniterCallerSchemaUtils = IgniterCallerSchemaUtils;
|
|
1631
2309
|
exports.IgniterCallerUrlUtils = IgniterCallerUrlUtils;
|
|
2310
|
+
exports.MockCallerStoreAdapter = MockCallerStoreAdapter;
|
|
1632
2311
|
//# sourceMappingURL=index.js.map
|
|
1633
2312
|
//# sourceMappingURL=index.js.map
|