kugelaudio 0.1.2 → 0.1.5

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/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to the KugelAudio JavaScript/TypeScript SDK will be document
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.3] - 2024-12-25
9
+
10
+ ### Fixed
11
+ - Fixed WebSocket authentication: now correctly uses `master_key` query param when `isMasterKey: true` is set, instead of always using `api_key`
12
+ - Added both `X-API-Key` header and `Authorization: Bearer` header for HTTP requests
13
+
8
14
  ## [0.1.0] - 2024-12-17
9
15
 
10
16
  ### Added
package/dist/index.d.mts CHANGED
@@ -151,8 +151,12 @@ interface StreamCallbacks {
151
151
  * KugelAudio client options.
152
152
  */
153
153
  interface KugelAudioOptions {
154
- /** Your KugelAudio API key */
154
+ /** Your KugelAudio API key or JWT token */
155
155
  apiKey: string;
156
+ /** Whether apiKey is a master key (for internal/server-side use). Master keys bypass billing. */
157
+ isMasterKey?: boolean;
158
+ /** Whether apiKey is a JWT token (for user authentication). Takes precedence over isMasterKey. */
159
+ isToken?: boolean;
156
160
  /** API base URL (default: https://api.kugelaudio.com) */
157
161
  apiUrl?: string;
158
162
  /** TTS server URL (default: https://eu.kugelaudio.com) */
@@ -210,6 +214,10 @@ declare class TTSResource {
210
214
  * Returns complete audio after all chunks are received.
211
215
  */
212
216
  generate(options: GenerateOptions): Promise<AudioResponse>;
217
+ /**
218
+ * Build the WebSocket URL with appropriate auth param.
219
+ */
220
+ private buildWsUrl;
213
221
  /**
214
222
  * Get or create a WebSocket connection for connection pooling.
215
223
  * This avoids the ~220ms connect overhead on each request.
@@ -270,6 +278,8 @@ declare class TTSResource {
270
278
  */
271
279
  declare class KugelAudio {
272
280
  private _apiKey;
281
+ private _isMasterKey;
282
+ private _isToken;
273
283
  private _apiUrl;
274
284
  private _ttsUrl;
275
285
  private _timeout;
@@ -282,6 +292,10 @@ declare class KugelAudio {
282
292
  constructor(options: KugelAudioOptions);
283
293
  /** Get API key */
284
294
  get apiKey(): string;
295
+ /** Check if using master key authentication */
296
+ get isMasterKey(): boolean;
297
+ /** Check if using JWT token authentication */
298
+ get isToken(): boolean;
285
299
  /** Get TTS URL */
286
300
  get ttsUrl(): string;
287
301
  /**
package/dist/index.d.ts CHANGED
@@ -151,8 +151,12 @@ interface StreamCallbacks {
151
151
  * KugelAudio client options.
152
152
  */
153
153
  interface KugelAudioOptions {
154
- /** Your KugelAudio API key */
154
+ /** Your KugelAudio API key or JWT token */
155
155
  apiKey: string;
156
+ /** Whether apiKey is a master key (for internal/server-side use). Master keys bypass billing. */
157
+ isMasterKey?: boolean;
158
+ /** Whether apiKey is a JWT token (for user authentication). Takes precedence over isMasterKey. */
159
+ isToken?: boolean;
156
160
  /** API base URL (default: https://api.kugelaudio.com) */
157
161
  apiUrl?: string;
158
162
  /** TTS server URL (default: https://eu.kugelaudio.com) */
@@ -210,6 +214,10 @@ declare class TTSResource {
210
214
  * Returns complete audio after all chunks are received.
211
215
  */
212
216
  generate(options: GenerateOptions): Promise<AudioResponse>;
217
+ /**
218
+ * Build the WebSocket URL with appropriate auth param.
219
+ */
220
+ private buildWsUrl;
213
221
  /**
214
222
  * Get or create a WebSocket connection for connection pooling.
215
223
  * This avoids the ~220ms connect overhead on each request.
@@ -270,6 +278,8 @@ declare class TTSResource {
270
278
  */
271
279
  declare class KugelAudio {
272
280
  private _apiKey;
281
+ private _isMasterKey;
282
+ private _isToken;
273
283
  private _apiUrl;
274
284
  private _ttsUrl;
275
285
  private _timeout;
@@ -282,6 +292,10 @@ declare class KugelAudio {
282
292
  constructor(options: KugelAudioOptions);
283
293
  /** Get API key */
284
294
  get apiKey(): string;
295
+ /** Check if using master key authentication */
296
+ get isMasterKey(): boolean;
297
+ /** Check if using JWT token authentication */
298
+ get isToken(): boolean;
285
299
  /** Get TTS URL */
286
300
  get ttsUrl(): string;
287
301
  /**
package/dist/index.js CHANGED
@@ -248,13 +248,27 @@ var TTSResource = class {
248
248
  rtf: finalStats ? finalStats.rtf : 0
249
249
  };
250
250
  }
251
+ /**
252
+ * Build the WebSocket URL with appropriate auth param.
253
+ */
254
+ buildWsUrl() {
255
+ const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
256
+ let authParam;
257
+ if (this.client.isToken) {
258
+ authParam = "token";
259
+ } else if (this.client.isMasterKey) {
260
+ authParam = "master_key";
261
+ } else {
262
+ authParam = "api_key";
263
+ }
264
+ return `${wsUrl}/ws/tts?${authParam}=${this.client.apiKey}`;
265
+ }
251
266
  /**
252
267
  * Get or create a WebSocket connection for connection pooling.
253
268
  * This avoids the ~220ms connect overhead on each request.
254
269
  */
255
270
  async getConnection() {
256
- const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
257
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
271
+ const url = this.buildWsUrl();
258
272
  if (this.wsConnection && this.wsUrl === url && this.wsConnection.readyState === WebSocket.OPEN) {
259
273
  return this.wsConnection;
260
274
  }
@@ -385,8 +399,7 @@ var TTSResource = class {
385
399
  */
386
400
  streamWithoutPooling(options, callbacks) {
387
401
  return new Promise((resolve, reject) => {
388
- const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
389
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
402
+ const url = this.buildWsUrl();
390
403
  const ws = new WebSocket(url);
391
404
  ws.onopen = () => {
392
405
  callbacks.onOpen?.();
@@ -485,6 +498,8 @@ var KugelAudio = class {
485
498
  throw new Error("API key is required");
486
499
  }
487
500
  this._apiKey = options.apiKey;
501
+ this._isMasterKey = options.isMasterKey || false;
502
+ this._isToken = options.isToken || false;
488
503
  this._apiUrl = (options.apiUrl || DEFAULT_API_URL).replace(/\/$/, "");
489
504
  this._ttsUrl = (options.ttsUrl || this._apiUrl).replace(/\/$/, "");
490
505
  this._timeout = options.timeout || 6e4;
@@ -496,6 +511,14 @@ var KugelAudio = class {
496
511
  get apiKey() {
497
512
  return this._apiKey;
498
513
  }
514
+ /** Check if using master key authentication */
515
+ get isMasterKey() {
516
+ return this._isMasterKey;
517
+ }
518
+ /** Check if using JWT token authentication */
519
+ get isToken() {
520
+ return this._isToken;
521
+ }
499
522
  /** Get TTS URL */
500
523
  get ttsUrl() {
501
524
  return this._ttsUrl;
package/dist/index.mjs CHANGED
@@ -212,13 +212,27 @@ var TTSResource = class {
212
212
  rtf: finalStats ? finalStats.rtf : 0
213
213
  };
214
214
  }
215
+ /**
216
+ * Build the WebSocket URL with appropriate auth param.
217
+ */
218
+ buildWsUrl() {
219
+ const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
220
+ let authParam;
221
+ if (this.client.isToken) {
222
+ authParam = "token";
223
+ } else if (this.client.isMasterKey) {
224
+ authParam = "master_key";
225
+ } else {
226
+ authParam = "api_key";
227
+ }
228
+ return `${wsUrl}/ws/tts?${authParam}=${this.client.apiKey}`;
229
+ }
215
230
  /**
216
231
  * Get or create a WebSocket connection for connection pooling.
217
232
  * This avoids the ~220ms connect overhead on each request.
218
233
  */
219
234
  async getConnection() {
220
- const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
221
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
235
+ const url = this.buildWsUrl();
222
236
  if (this.wsConnection && this.wsUrl === url && this.wsConnection.readyState === WebSocket.OPEN) {
223
237
  return this.wsConnection;
224
238
  }
@@ -349,8 +363,7 @@ var TTSResource = class {
349
363
  */
350
364
  streamWithoutPooling(options, callbacks) {
351
365
  return new Promise((resolve, reject) => {
352
- const wsUrl = this.client.ttsUrl.replace("https://", "wss://").replace("http://", "ws://");
353
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
366
+ const url = this.buildWsUrl();
354
367
  const ws = new WebSocket(url);
355
368
  ws.onopen = () => {
356
369
  callbacks.onOpen?.();
@@ -449,6 +462,8 @@ var KugelAudio = class {
449
462
  throw new Error("API key is required");
450
463
  }
451
464
  this._apiKey = options.apiKey;
465
+ this._isMasterKey = options.isMasterKey || false;
466
+ this._isToken = options.isToken || false;
452
467
  this._apiUrl = (options.apiUrl || DEFAULT_API_URL).replace(/\/$/, "");
453
468
  this._ttsUrl = (options.ttsUrl || this._apiUrl).replace(/\/$/, "");
454
469
  this._timeout = options.timeout || 6e4;
@@ -460,6 +475,14 @@ var KugelAudio = class {
460
475
  get apiKey() {
461
476
  return this._apiKey;
462
477
  }
478
+ /** Check if using master key authentication */
479
+ get isMasterKey() {
480
+ return this._isMasterKey;
481
+ }
482
+ /** Check if using JWT token authentication */
483
+ get isToken() {
484
+ return this._isToken;
485
+ }
463
486
  /** Get TTS URL */
464
487
  get ttsUrl() {
465
488
  return this._ttsUrl;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kugelaudio",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Official JavaScript/TypeScript SDK for KugelAudio TTS API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/client.ts CHANGED
@@ -159,14 +159,30 @@ class TTSResource {
159
159
  }
160
160
 
161
161
  /**
162
- * Get or create a WebSocket connection for connection pooling.
163
- * This avoids the ~220ms connect overhead on each request.
162
+ * Build the WebSocket URL with appropriate auth param.
164
163
  */
165
- private async getConnection(): Promise<WebSocket> {
164
+ private buildWsUrl(): string {
166
165
  const wsUrl = this.client.ttsUrl
167
166
  .replace('https://', 'wss://')
168
167
  .replace('http://', 'ws://');
169
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
168
+ // Use token param for JWT tokens, master_key for master keys (bypasses billing), api_key for regular keys
169
+ let authParam: string;
170
+ if (this.client.isToken) {
171
+ authParam = 'token';
172
+ } else if (this.client.isMasterKey) {
173
+ authParam = 'master_key';
174
+ } else {
175
+ authParam = 'api_key';
176
+ }
177
+ return `${wsUrl}/ws/tts?${authParam}=${this.client.apiKey}`;
178
+ }
179
+
180
+ /**
181
+ * Get or create a WebSocket connection for connection pooling.
182
+ * This avoids the ~220ms connect overhead on each request.
183
+ */
184
+ private async getConnection(): Promise<WebSocket> {
185
+ const url = this.buildWsUrl();
170
186
 
171
187
  // Return existing connection if valid
172
188
  if (
@@ -338,11 +354,7 @@ class TTSResource {
338
354
  callbacks: StreamCallbacks
339
355
  ): Promise<void> {
340
356
  return new Promise((resolve, reject) => {
341
- const wsUrl = this.client.ttsUrl
342
- .replace('https://', 'wss://')
343
- .replace('http://', 'ws://');
344
- const url = `${wsUrl}/ws/tts?api_key=${this.client.apiKey}`;
345
-
357
+ const url = this.buildWsUrl();
346
358
  const ws = new WebSocket(url);
347
359
 
348
360
  ws.onopen = () => {
@@ -475,6 +487,8 @@ class TTSResource {
475
487
  */
476
488
  export class KugelAudio {
477
489
  private _apiKey: string;
490
+ private _isMasterKey: boolean;
491
+ private _isToken: boolean;
478
492
  private _apiUrl: string;
479
493
  private _ttsUrl: string;
480
494
  private _timeout: number;
@@ -492,6 +506,8 @@ export class KugelAudio {
492
506
  }
493
507
 
494
508
  this._apiKey = options.apiKey;
509
+ this._isMasterKey = options.isMasterKey || false;
510
+ this._isToken = options.isToken || false;
495
511
  this._apiUrl = (options.apiUrl || DEFAULT_API_URL).replace(/\/$/, '');
496
512
  // If ttsUrl not specified, use apiUrl (backend proxies to TTS server)
497
513
  this._ttsUrl = (options.ttsUrl || this._apiUrl).replace(/\/$/, '');
@@ -507,6 +523,16 @@ export class KugelAudio {
507
523
  return this._apiKey;
508
524
  }
509
525
 
526
+ /** Check if using master key authentication */
527
+ get isMasterKey(): boolean {
528
+ return this._isMasterKey;
529
+ }
530
+
531
+ /** Check if using JWT token authentication */
532
+ get isToken(): boolean {
533
+ return this._isToken;
534
+ }
535
+
510
536
  /** Get TTS URL */
511
537
  get ttsUrl(): string {
512
538
  return this._ttsUrl;
package/src/types.ts CHANGED
@@ -163,8 +163,12 @@ export interface StreamCallbacks {
163
163
  * KugelAudio client options.
164
164
  */
165
165
  export interface KugelAudioOptions {
166
- /** Your KugelAudio API key */
166
+ /** Your KugelAudio API key or JWT token */
167
167
  apiKey: string;
168
+ /** Whether apiKey is a master key (for internal/server-side use). Master keys bypass billing. */
169
+ isMasterKey?: boolean;
170
+ /** Whether apiKey is a JWT token (for user authentication). Takes precedence over isMasterKey. */
171
+ isToken?: boolean;
168
172
  /** API base URL (default: https://api.kugelaudio.com) */
169
173
  apiUrl?: string;
170
174
  /** TTS server URL (default: https://eu.kugelaudio.com) */