zlient 3.1.1 → 3.2.1

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/dist/index.js CHANGED
@@ -72,6 +72,179 @@ var BearerTokenAuth = class {
72
72
  }
73
73
  };
74
74
  //#endregion
75
+ //#region lib/logger.ts
76
+ /**
77
+ * Log levels for structured logging.
78
+ */
79
+ let LogLevel = /* @__PURE__ */ function(LogLevel) {
80
+ LogLevel["DEBUG"] = "debug";
81
+ LogLevel["INFO"] = "info";
82
+ LogLevel["WARN"] = "warn";
83
+ LogLevel["ERROR"] = "error";
84
+ return LogLevel;
85
+ }({});
86
+ /**
87
+ * Default console logger implementation.
88
+ * Formats log entries as JSON for easy parsing.
89
+ */
90
+ var ConsoleLogger = class {
91
+ constructor(minLevel = LogLevel.INFO) {
92
+ this.minLevel = minLevel;
93
+ }
94
+ log(entry) {
95
+ const levels = [
96
+ LogLevel.DEBUG,
97
+ LogLevel.INFO,
98
+ LogLevel.WARN,
99
+ LogLevel.ERROR
100
+ ];
101
+ if (levels.indexOf(entry.level) < levels.indexOf(this.minLevel)) return;
102
+ const output = {
103
+ ...entry,
104
+ error: entry.error ? {
105
+ message: entry.error.message,
106
+ stack: entry.error.stack,
107
+ name: entry.error.name
108
+ } : void 0
109
+ };
110
+ switch (entry.level) {
111
+ case LogLevel.DEBUG:
112
+ console.debug(JSON.stringify(output));
113
+ break;
114
+ case LogLevel.INFO:
115
+ console.info(JSON.stringify(output));
116
+ break;
117
+ case LogLevel.WARN:
118
+ console.warn(JSON.stringify(output));
119
+ break;
120
+ case LogLevel.ERROR:
121
+ console.error(JSON.stringify(output));
122
+ break;
123
+ }
124
+ }
125
+ };
126
+ /**
127
+ * No-op logger that discards all log entries.
128
+ * Use this in production if you don't want any logging.
129
+ */
130
+ var NoOpLogger = class {
131
+ log(_entry) {}
132
+ };
133
+ /**
134
+ * Utility class for creating structured log entries.
135
+ */
136
+ var LoggerUtil = class {
137
+ constructor(logger) {
138
+ this.logger = logger;
139
+ }
140
+ debug(message, context) {
141
+ this.logger.log({
142
+ level: LogLevel.DEBUG,
143
+ message,
144
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
145
+ context
146
+ });
147
+ }
148
+ info(message, context) {
149
+ this.logger.log({
150
+ level: LogLevel.INFO,
151
+ message,
152
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
153
+ context
154
+ });
155
+ }
156
+ warn(message, context) {
157
+ this.logger.log({
158
+ level: LogLevel.WARN,
159
+ message,
160
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
161
+ context
162
+ });
163
+ }
164
+ error(message, error, context) {
165
+ this.logger.log({
166
+ level: LogLevel.ERROR,
167
+ message,
168
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
169
+ context,
170
+ error
171
+ });
172
+ }
173
+ };
174
+ //#endregion
175
+ //#region lib/metrics.ts
176
+ /**
177
+ * No-op metrics collector that discards all metrics.
178
+ */
179
+ var NoOpMetricsCollector = class {
180
+ collect(_metrics) {}
181
+ };
182
+ /**
183
+ * In-memory metrics collector for testing and development.
184
+ * Stores metrics in memory with configurable retention.
185
+ */
186
+ var InMemoryMetricsCollector = class {
187
+ constructor(maxEntries = 1e3) {
188
+ this.metrics = [];
189
+ this.maxEntries = maxEntries;
190
+ }
191
+ collect(metrics) {
192
+ this.metrics.push(metrics);
193
+ if (this.metrics.length > this.maxEntries) this.metrics.shift();
194
+ }
195
+ /**
196
+ * Get all collected metrics.
197
+ */
198
+ getMetrics() {
199
+ return [...this.metrics];
200
+ }
201
+ /**
202
+ * Get metrics summary statistics.
203
+ */
204
+ getSummary() {
205
+ if (this.metrics.length === 0) return {
206
+ total: 0,
207
+ successful: 0,
208
+ failed: 0,
209
+ avgDurationMs: 0,
210
+ minDurationMs: 0,
211
+ maxDurationMs: 0
212
+ };
213
+ const successful = this.metrics.filter((m) => m.success).length;
214
+ let sum = 0;
215
+ let min = Infinity;
216
+ let max = -Infinity;
217
+ for (const m of this.metrics) {
218
+ const d = m.durationMs;
219
+ sum += d;
220
+ if (d < min) min = d;
221
+ if (d > max) max = d;
222
+ }
223
+ return {
224
+ total: this.metrics.length,
225
+ successful,
226
+ failed: this.metrics.length - successful,
227
+ avgDurationMs: sum / this.metrics.length,
228
+ minDurationMs: min === Infinity ? 0 : min,
229
+ maxDurationMs: max === -Infinity ? 0 : max
230
+ };
231
+ }
232
+ /**
233
+ * Clear all collected metrics.
234
+ */
235
+ clear() {
236
+ this.metrics = [];
237
+ }
238
+ };
239
+ /**
240
+ * Console-based metrics collector for debugging.
241
+ */
242
+ var ConsoleMetricsCollector = class {
243
+ collect(metrics) {
244
+ console.log("[METRICS]", JSON.stringify(metrics));
245
+ }
246
+ };
247
+ //#endregion
75
248
  //#region lib/types.ts
76
249
  const HTTPMethod = {
77
250
  GET: "GET",
@@ -321,7 +494,163 @@ function isStandardSchema(value) {
321
494
  return "~standard" in schema && typeof schema["~standard"] === "object" && schema["~standard"] !== null && schema["~standard"].version === 1 && typeof schema["~standard"].validate === "function";
322
495
  }
323
496
  //#endregion
324
- //#region lib/endpoint/base-endpoint.ts
497
+ //#region lib/sse/sse-client.ts
498
+ var SSEConnectionImpl = class {
499
+ constructor(url, responseSchema, skipResponseValidation = false, withCredentials = false) {
500
+ this.responseSchema = responseSchema;
501
+ this.skipResponseValidation = skipResponseValidation;
502
+ this.handlers = /* @__PURE__ */ new Map();
503
+ if (typeof EventSource === "undefined") throw new Error("EventSource is not defined. Ensure you are in a supported environment.");
504
+ this.es = new EventSource(url, { withCredentials });
505
+ this.es.onopen = (event) => this.emit("open", event);
506
+ this.es.onerror = (event) => this.emit("error", event);
507
+ this.es.onmessage = async (event) => {
508
+ let data = event.data;
509
+ try {
510
+ if (typeof data === "string") try {
511
+ data = JSON.parse(data);
512
+ } catch {}
513
+ const schema = this.getSchema("message");
514
+ if (!this.skipResponseValidation && schema) data = await parseOrThrow(schema, data);
515
+ this.emit("message", data);
516
+ } catch (error) {
517
+ this.emit("error", error);
518
+ }
519
+ };
520
+ }
521
+ getSchema(event) {
522
+ if (!this.responseSchema) return void 0;
523
+ if ("~standard" in this.responseSchema) {
524
+ if (event === "message") return this.responseSchema;
525
+ return;
526
+ }
527
+ return this.responseSchema[event];
528
+ }
529
+ on(event, handler) {
530
+ if (!this.handlers.has(event)) {
531
+ this.handlers.set(event, /* @__PURE__ */ new Set());
532
+ if (event !== "message" && event !== "open" && event !== "error") this.es.addEventListener(event, async (ev) => {
533
+ let data = ev.data;
534
+ try {
535
+ if (typeof data === "string") try {
536
+ data = JSON.parse(data);
537
+ } catch {}
538
+ const schema = this.getSchema(event);
539
+ if (!this.skipResponseValidation && schema) data = await parseOrThrow(schema, data);
540
+ this.emit(event, data);
541
+ } catch (error) {
542
+ this.emit("error", error);
543
+ }
544
+ });
545
+ }
546
+ this.handlers.get(event).add(handler);
547
+ }
548
+ off(event, handler) {
549
+ const handlers = this.handlers.get(event);
550
+ if (handlers) handlers.delete(handler);
551
+ }
552
+ emit(event, ...args) {
553
+ const handlers = this.handlers.get(event);
554
+ if (handlers) handlers.forEach((handler) => handler(...args));
555
+ }
556
+ close() {
557
+ this.es.close();
558
+ }
559
+ get readyState() {
560
+ return this.es.readyState;
561
+ }
562
+ };
563
+ //#endregion
564
+ //#region lib/sse/sse-endpoint.ts
565
+ var SSEEndpointImpl = class {
566
+ constructor(client, config) {
567
+ this.client = client;
568
+ this.config = config;
569
+ }
570
+ createCall() {
571
+ return (params) => {
572
+ const { query, pathParams } = params || {};
573
+ let pathStr;
574
+ if (typeof this.config.path === "function") {
575
+ if (!pathParams) throw new Error("Path function requires pathParams");
576
+ pathStr = this.config.path(pathParams);
577
+ } else pathStr = this.config.path;
578
+ return new SSEConnectionImpl(`${this.client.getBaseUrl(this.config.advanced?.baseUrlKey || "default")}${pathStr}${toQueryString(query)}`, this.config.response, this.config.advanced?.skipResponseValidation, this.config.advanced?.withCredentials);
579
+ };
580
+ }
581
+ };
582
+ //#endregion
583
+ //#region lib/ws/ws-client.ts
584
+ var WSConnectionImpl = class {
585
+ constructor(url, sendSchema, receiveSchema, skipRequestValidation = false, skipResponseValidation = false, protocols) {
586
+ this.sendSchema = sendSchema;
587
+ this.receiveSchema = receiveSchema;
588
+ this.skipRequestValidation = skipRequestValidation;
589
+ this.skipResponseValidation = skipResponseValidation;
590
+ this.handlers = /* @__PURE__ */ new Map();
591
+ if (typeof WebSocket === "undefined") throw new Error("WebSocket is not defined. Ensure you are in a supported environment.");
592
+ this.ws = new WebSocket(url, protocols);
593
+ this.ws.onopen = () => this.emit("open");
594
+ this.ws.onclose = (event) => this.emit("close", event);
595
+ this.ws.onerror = (event) => this.emit("error", event);
596
+ this.ws.onmessage = async (event) => {
597
+ let data = event.data;
598
+ try {
599
+ if (typeof data === "string") try {
600
+ data = JSON.parse(data);
601
+ } catch {}
602
+ if (!this.skipResponseValidation && this.receiveSchema) data = await parseOrThrow(this.receiveSchema, data);
603
+ this.emit("message", data);
604
+ } catch (error) {
605
+ this.emit("error", error);
606
+ }
607
+ };
608
+ }
609
+ async send(data) {
610
+ if (!this.skipRequestValidation && this.sendSchema) await parseOrThrow(this.sendSchema, data);
611
+ const message = data != null && typeof data === "object" ? JSON.stringify(data) : data;
612
+ this.ws.send(message);
613
+ }
614
+ on(event, handler) {
615
+ if (!this.handlers.has(event)) this.handlers.set(event, /* @__PURE__ */ new Set());
616
+ this.handlers.get(event).add(handler);
617
+ }
618
+ off(event, handler) {
619
+ const handlers = this.handlers.get(event);
620
+ if (handlers) handlers.delete(handler);
621
+ }
622
+ emit(event, ...args) {
623
+ const handlers = this.handlers.get(event);
624
+ if (handlers) handlers.forEach((handler) => handler(...args));
625
+ }
626
+ close(code, reason) {
627
+ this.ws.close(code, reason);
628
+ }
629
+ get readyState() {
630
+ return this.ws.readyState;
631
+ }
632
+ };
633
+ //#endregion
634
+ //#region lib/ws/ws-endpoint.ts
635
+ var WSEndpointImpl = class {
636
+ constructor(client, config) {
637
+ this.client = client;
638
+ this.config = config;
639
+ }
640
+ createCall() {
641
+ return (params) => {
642
+ const { query, pathParams, protocols } = params || {};
643
+ let pathStr;
644
+ if (typeof this.config.path === "function") {
645
+ if (!pathParams) throw new Error("Path function requires pathParams");
646
+ pathStr = this.config.path(pathParams);
647
+ } else pathStr = this.config.path;
648
+ return new WSConnectionImpl(`${this.client.getBaseUrl(this.config.advanced?.baseUrlKey || "default").replace(/^http/, "ws")}${pathStr}${toQueryString(query)}`, this.config.send, this.config.receive, this.config.advanced?.skipRequestValidation, this.config.advanced?.skipResponseValidation, protocols);
649
+ };
650
+ }
651
+ };
652
+ //#endregion
653
+ //#region lib/http/http-endpoint.ts
325
654
  var EndpointImpl = class {
326
655
  constructor(client, config) {
327
656
  this.client = client;
@@ -363,179 +692,6 @@ var EndpointImpl = class {
363
692
  }
364
693
  };
365
694
  //#endregion
366
- //#region lib/logger.ts
367
- /**
368
- * Log levels for structured logging.
369
- */
370
- let LogLevel = /* @__PURE__ */ function(LogLevel) {
371
- LogLevel["DEBUG"] = "debug";
372
- LogLevel["INFO"] = "info";
373
- LogLevel["WARN"] = "warn";
374
- LogLevel["ERROR"] = "error";
375
- return LogLevel;
376
- }({});
377
- /**
378
- * Default console logger implementation.
379
- * Formats log entries as JSON for easy parsing.
380
- */
381
- var ConsoleLogger = class {
382
- constructor(minLevel = LogLevel.INFO) {
383
- this.minLevel = minLevel;
384
- }
385
- log(entry) {
386
- const levels = [
387
- LogLevel.DEBUG,
388
- LogLevel.INFO,
389
- LogLevel.WARN,
390
- LogLevel.ERROR
391
- ];
392
- if (levels.indexOf(entry.level) < levels.indexOf(this.minLevel)) return;
393
- const output = {
394
- ...entry,
395
- error: entry.error ? {
396
- message: entry.error.message,
397
- stack: entry.error.stack,
398
- name: entry.error.name
399
- } : void 0
400
- };
401
- switch (entry.level) {
402
- case LogLevel.DEBUG:
403
- console.debug(JSON.stringify(output));
404
- break;
405
- case LogLevel.INFO:
406
- console.info(JSON.stringify(output));
407
- break;
408
- case LogLevel.WARN:
409
- console.warn(JSON.stringify(output));
410
- break;
411
- case LogLevel.ERROR:
412
- console.error(JSON.stringify(output));
413
- break;
414
- }
415
- }
416
- };
417
- /**
418
- * No-op logger that discards all log entries.
419
- * Use this in production if you don't want any logging.
420
- */
421
- var NoOpLogger = class {
422
- log(_entry) {}
423
- };
424
- /**
425
- * Utility class for creating structured log entries.
426
- */
427
- var LoggerUtil = class {
428
- constructor(logger) {
429
- this.logger = logger;
430
- }
431
- debug(message, context) {
432
- this.logger.log({
433
- level: LogLevel.DEBUG,
434
- message,
435
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
436
- context
437
- });
438
- }
439
- info(message, context) {
440
- this.logger.log({
441
- level: LogLevel.INFO,
442
- message,
443
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
444
- context
445
- });
446
- }
447
- warn(message, context) {
448
- this.logger.log({
449
- level: LogLevel.WARN,
450
- message,
451
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
452
- context
453
- });
454
- }
455
- error(message, error, context) {
456
- this.logger.log({
457
- level: LogLevel.ERROR,
458
- message,
459
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
460
- context,
461
- error
462
- });
463
- }
464
- };
465
- //#endregion
466
- //#region lib/metrics.ts
467
- /**
468
- * No-op metrics collector that discards all metrics.
469
- */
470
- var NoOpMetricsCollector = class {
471
- collect(_metrics) {}
472
- };
473
- /**
474
- * In-memory metrics collector for testing and development.
475
- * Stores metrics in memory with configurable retention.
476
- */
477
- var InMemoryMetricsCollector = class {
478
- constructor(maxEntries = 1e3) {
479
- this.metrics = [];
480
- this.maxEntries = maxEntries;
481
- }
482
- collect(metrics) {
483
- this.metrics.push(metrics);
484
- if (this.metrics.length > this.maxEntries) this.metrics.shift();
485
- }
486
- /**
487
- * Get all collected metrics.
488
- */
489
- getMetrics() {
490
- return [...this.metrics];
491
- }
492
- /**
493
- * Get metrics summary statistics.
494
- */
495
- getSummary() {
496
- if (this.metrics.length === 0) return {
497
- total: 0,
498
- successful: 0,
499
- failed: 0,
500
- avgDurationMs: 0,
501
- minDurationMs: 0,
502
- maxDurationMs: 0
503
- };
504
- const successful = this.metrics.filter((m) => m.success).length;
505
- let sum = 0;
506
- let min = Infinity;
507
- let max = -Infinity;
508
- for (const m of this.metrics) {
509
- const d = m.durationMs;
510
- sum += d;
511
- if (d < min) min = d;
512
- if (d > max) max = d;
513
- }
514
- return {
515
- total: this.metrics.length,
516
- successful,
517
- failed: this.metrics.length - successful,
518
- avgDurationMs: sum / this.metrics.length,
519
- minDurationMs: min === Infinity ? 0 : min,
520
- maxDurationMs: max === -Infinity ? 0 : max
521
- };
522
- }
523
- /**
524
- * Clear all collected metrics.
525
- */
526
- clear() {
527
- this.metrics = [];
528
- }
529
- };
530
- /**
531
- * Console-based metrics collector for debugging.
532
- */
533
- var ConsoleMetricsCollector = class {
534
- collect(metrics) {
535
- console.log("[METRICS]", JSON.stringify(metrics));
536
- }
537
- };
538
- //#endregion
539
695
  //#region lib/http/http-client.ts
540
696
  /**
541
697
  * HTTP client with built-in authentication, and interceptors.
@@ -896,8 +1052,26 @@ var HttpClient = class {
896
1052
  const endpoint = new EndpointImpl(this, config);
897
1053
  return (params) => endpoint.call(params);
898
1054
  }
1055
+ /**
1056
+ * Create a strongly-typed WebSocket endpoint builder.
1057
+ *
1058
+ * @param config - WebSocket endpoint configuration
1059
+ * @returns WebSocket endpoint call function
1060
+ */
1061
+ createWebSocket(config) {
1062
+ return new WSEndpointImpl(this, config).createCall();
1063
+ }
1064
+ /**
1065
+ * Create a strongly-typed Server-Sent Events (SSE) endpoint builder.
1066
+ *
1067
+ * @param config - SSE endpoint configuration
1068
+ * @returns SSE endpoint call function
1069
+ */
1070
+ createSSE(config) {
1071
+ return new SSEEndpointImpl(this, config).createCall();
1072
+ }
899
1073
  };
900
1074
  //#endregion
901
- export { ApiError, ApiKeyAuth, BearerTokenAuth, ConsoleLogger, ConsoleMetricsCollector, EndpointImpl, HTTPMethod, HTTPStatusCode, HttpClient, InMemoryMetricsCollector, LogLevel, LoggerUtil, NoAuth, NoOpLogger, NoOpMetricsCollector, SchemaDefinitionError, isStandardSchema, parseOrThrow, safeParse, toQueryString };
1075
+ export { ApiError, ApiKeyAuth, BearerTokenAuth, ConsoleLogger, ConsoleMetricsCollector, EndpointImpl, HTTPMethod, HTTPStatusCode, HttpClient, InMemoryMetricsCollector, LogLevel, LoggerUtil, NoAuth, NoOpLogger, NoOpMetricsCollector, SSEConnectionImpl, SSEEndpointImpl, SchemaDefinitionError, WSConnectionImpl, WSEndpointImpl, isStandardSchema, parseOrThrow, safeParse, toQueryString };
902
1076
 
903
1077
  //# sourceMappingURL=index.js.map