@loonylabs/tts-middleware 0.1.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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/dist/index.d.ts +22 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +39 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/middleware/services/tts/index.d.ts +30 -0
  8. package/dist/middleware/services/tts/index.d.ts.map +1 -0
  9. package/dist/middleware/services/tts/index.js +69 -0
  10. package/dist/middleware/services/tts/index.js.map +1 -0
  11. package/dist/middleware/services/tts/providers/azure-provider.d.ts +131 -0
  12. package/dist/middleware/services/tts/providers/azure-provider.d.ts.map +1 -0
  13. package/dist/middleware/services/tts/providers/azure-provider.js +375 -0
  14. package/dist/middleware/services/tts/providers/azure-provider.js.map +1 -0
  15. package/dist/middleware/services/tts/providers/base-tts-provider.d.ts +204 -0
  16. package/dist/middleware/services/tts/providers/base-tts-provider.d.ts.map +1 -0
  17. package/dist/middleware/services/tts/providers/base-tts-provider.js +267 -0
  18. package/dist/middleware/services/tts/providers/base-tts-provider.js.map +1 -0
  19. package/dist/middleware/services/tts/providers/edenai-provider.d.ts +112 -0
  20. package/dist/middleware/services/tts/providers/edenai-provider.d.ts.map +1 -0
  21. package/dist/middleware/services/tts/providers/edenai-provider.js +289 -0
  22. package/dist/middleware/services/tts/providers/edenai-provider.js.map +1 -0
  23. package/dist/middleware/services/tts/providers/index.d.ts +9 -0
  24. package/dist/middleware/services/tts/providers/index.d.ts.map +1 -0
  25. package/dist/middleware/services/tts/providers/index.js +29 -0
  26. package/dist/middleware/services/tts/providers/index.js.map +1 -0
  27. package/dist/middleware/services/tts/tts.service.d.ts +175 -0
  28. package/dist/middleware/services/tts/tts.service.d.ts.map +1 -0
  29. package/dist/middleware/services/tts/tts.service.js +287 -0
  30. package/dist/middleware/services/tts/tts.service.js.map +1 -0
  31. package/dist/middleware/services/tts/types/common.types.d.ts +303 -0
  32. package/dist/middleware/services/tts/types/common.types.d.ts.map +1 -0
  33. package/dist/middleware/services/tts/types/common.types.js +42 -0
  34. package/dist/middleware/services/tts/types/common.types.js.map +1 -0
  35. package/dist/middleware/services/tts/types/index.d.ts +22 -0
  36. package/dist/middleware/services/tts/types/index.d.ts.map +1 -0
  37. package/dist/middleware/services/tts/types/index.js +46 -0
  38. package/dist/middleware/services/tts/types/index.js.map +1 -0
  39. package/dist/middleware/services/tts/types/provider-options.types.d.ts +414 -0
  40. package/dist/middleware/services/tts/types/provider-options.types.d.ts.map +1 -0
  41. package/dist/middleware/services/tts/types/provider-options.types.js +71 -0
  42. package/dist/middleware/services/tts/types/provider-options.types.js.map +1 -0
  43. package/dist/middleware/services/tts/utils/character-counter.utils.d.ts +160 -0
  44. package/dist/middleware/services/tts/utils/character-counter.utils.d.ts.map +1 -0
  45. package/dist/middleware/services/tts/utils/character-counter.utils.js +205 -0
  46. package/dist/middleware/services/tts/utils/character-counter.utils.js.map +1 -0
  47. package/dist/middleware/services/tts/utils/index.d.ts +9 -0
  48. package/dist/middleware/services/tts/utils/index.d.ts.map +1 -0
  49. package/dist/middleware/services/tts/utils/index.js +25 -0
  50. package/dist/middleware/services/tts/utils/index.js.map +1 -0
  51. package/dist/middleware/services/tts/utils/logger.utils.d.ts +116 -0
  52. package/dist/middleware/services/tts/utils/logger.utils.d.ts.map +1 -0
  53. package/dist/middleware/services/tts/utils/logger.utils.js +186 -0
  54. package/dist/middleware/services/tts/utils/logger.utils.js.map +1 -0
  55. package/dist/middleware/shared/config/tts.config.d.ts +147 -0
  56. package/dist/middleware/shared/config/tts.config.d.ts.map +1 -0
  57. package/dist/middleware/shared/config/tts.config.js +162 -0
  58. package/dist/middleware/shared/config/tts.config.js.map +1 -0
  59. package/package.json +94 -0
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ /**
3
+ * Azure Speech Services TTS Provider
4
+ *
5
+ * @description Implementation of TTS provider for Microsoft Azure Speech Services.
6
+ * This is the MVP provider for EU-compliant TTS synthesis.
7
+ *
8
+ * @see https://learn.microsoft.com/en-us/azure/ai-services/speech-service/
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.AzureProvider = void 0;
45
+ const sdk = __importStar(require("microsoft-cognitiveservices-speech-sdk"));
46
+ const types_1 = require("../types");
47
+ const base_tts_provider_1 = require("./base-tts-provider");
48
+ /**
49
+ * Azure Speech Services provider implementation
50
+ *
51
+ * @description Provides TTS synthesis using Microsoft Azure Speech Services.
52
+ * Supports emotion, style, and multiple audio formats.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const provider = new AzureProvider();
57
+ * const response = await provider.synthesize(
58
+ * "Hello World",
59
+ * "en-US-JennyNeural",
60
+ * {
61
+ * text: "Hello World",
62
+ * voice: { id: "en-US-JennyNeural" },
63
+ * audio: { speed: 1.0, format: "mp3" },
64
+ * providerOptions: { emotion: "cheerful" }
65
+ * }
66
+ * );
67
+ * ```
68
+ */
69
+ class AzureProvider extends base_tts_provider_1.BaseTTSProvider {
70
+ /**
71
+ * Creates a new Azure TTS provider
72
+ *
73
+ * @param config - Optional Azure configuration (uses env vars if not provided)
74
+ * @throws {InvalidConfigError} If required configuration is missing
75
+ */
76
+ constructor(config) {
77
+ super(types_1.TTSProvider.AZURE);
78
+ this.speechConfig = null;
79
+ // Load configuration from environment or provided config
80
+ this.config = {
81
+ subscriptionKey: config?.subscriptionKey || process.env.AZURE_SPEECH_KEY || '',
82
+ region: config?.region || process.env.AZURE_SPEECH_REGION || '',
83
+ endpoint: config?.endpoint || process.env.AZURE_SPEECH_ENDPOINT,
84
+ };
85
+ // Validate configuration
86
+ this.validateAzureConfig();
87
+ // Initialize speech config
88
+ this.initializeSpeechConfig();
89
+ }
90
+ /**
91
+ * Validate Azure-specific configuration
92
+ *
93
+ * @private
94
+ * @throws {InvalidConfigError} If configuration is invalid
95
+ */
96
+ validateAzureConfig() {
97
+ if (!this.config.subscriptionKey) {
98
+ throw new base_tts_provider_1.InvalidConfigError(this.providerName, 'Azure Speech subscription key is required (AZURE_SPEECH_KEY)');
99
+ }
100
+ if (!this.config.region) {
101
+ throw new base_tts_provider_1.InvalidConfigError(this.providerName, 'Azure Speech region is required (AZURE_SPEECH_REGION)');
102
+ }
103
+ }
104
+ /**
105
+ * Initialize Azure Speech SDK configuration
106
+ *
107
+ * @private
108
+ */
109
+ initializeSpeechConfig() {
110
+ try {
111
+ if (this.config.endpoint) {
112
+ this.speechConfig = sdk.SpeechConfig.fromEndpoint(new URL(this.config.endpoint), this.config.subscriptionKey);
113
+ }
114
+ else {
115
+ this.speechConfig = sdk.SpeechConfig.fromSubscription(this.config.subscriptionKey, this.config.region);
116
+ }
117
+ this.log('info', 'Azure Speech SDK initialized', {
118
+ region: this.config.region,
119
+ hasEndpoint: !!this.config.endpoint,
120
+ });
121
+ }
122
+ catch (error) {
123
+ throw new base_tts_provider_1.InvalidConfigError(this.providerName, `Failed to initialize Azure Speech SDK: ${error.message}`, error);
124
+ }
125
+ }
126
+ /**
127
+ * Synthesize text to speech using Azure Speech Services
128
+ *
129
+ * @param text - The input text to synthesize
130
+ * @param voiceId - The voice identifier (e.g., "en-US-JennyNeural")
131
+ * @param request - The full synthesis request with options
132
+ * @returns Promise resolving to the synthesis response
133
+ * @throws {InvalidConfigError} If configuration is invalid
134
+ * @throws {InvalidVoiceError} If voice is not found
135
+ * @throws {SynthesisFailedError} If synthesis fails
136
+ */
137
+ async synthesize(text, voiceId, request) {
138
+ // Validate configuration
139
+ this.validateConfig(request);
140
+ if (!this.speechConfig) {
141
+ throw new base_tts_provider_1.InvalidConfigError(this.providerName, 'Speech configuration not initialized');
142
+ }
143
+ const startTime = Date.now();
144
+ try {
145
+ // Extract options
146
+ const audioFormat = request.audio?.format || 'mp3';
147
+ const speed = request.audio?.speed || 1.0;
148
+ const sampleRate = request.audio?.sampleRate || 24000;
149
+ // Set audio output format
150
+ this.setAudioFormat(audioFormat, sampleRate);
151
+ // Generate SSML
152
+ const ssml = this.generateSSML(text, voiceId, request);
153
+ this.log('debug', 'Synthesizing with Azure', {
154
+ voiceId,
155
+ audioFormat,
156
+ speed,
157
+ sampleRate,
158
+ ssmlLength: ssml.length,
159
+ });
160
+ // Create synthesizer
161
+ const synthesizer = new sdk.SpeechSynthesizer(this.speechConfig);
162
+ // Synthesize speech
163
+ const audioBuffer = await this.synthesizeSSML(synthesizer, ssml);
164
+ // Calculate duration (estimated)
165
+ const duration = Date.now() - startTime;
166
+ // Count billable characters (original text, not SSML)
167
+ const characters = this.countCharacters(text);
168
+ this.log('info', 'Synthesis successful', {
169
+ voiceId,
170
+ characters,
171
+ duration,
172
+ audioSize: audioBuffer.length,
173
+ });
174
+ // Return response
175
+ return {
176
+ audio: audioBuffer,
177
+ metadata: {
178
+ provider: this.providerName,
179
+ voice: voiceId,
180
+ duration,
181
+ audioFormat,
182
+ sampleRate,
183
+ },
184
+ billing: {
185
+ characters,
186
+ },
187
+ };
188
+ }
189
+ catch (error) {
190
+ this.log('error', 'Synthesis failed', {
191
+ voiceId,
192
+ error: error.message,
193
+ });
194
+ throw this.handleError(error, 'during synthesis');
195
+ }
196
+ }
197
+ /**
198
+ * Set audio output format for Azure Speech SDK
199
+ *
200
+ * @private
201
+ * @param format - The audio format (mp3, wav, opus)
202
+ * @param sampleRate - The sample rate in Hz
203
+ */
204
+ setAudioFormat(format, sampleRate) {
205
+ if (!this.speechConfig) {
206
+ throw new base_tts_provider_1.InvalidConfigError(this.providerName, 'Speech configuration not initialized');
207
+ }
208
+ // Map format and sample rate to Azure format strings
209
+ const azureFormat = this.getAzureAudioFormat(format, sampleRate);
210
+ this.speechConfig.speechSynthesisOutputFormat = azureFormat;
211
+ this.log('debug', 'Audio format set', {
212
+ format,
213
+ sampleRate,
214
+ azureFormat: sdk.SpeechSynthesisOutputFormat[azureFormat],
215
+ });
216
+ }
217
+ /**
218
+ * Map audio format and sample rate to Azure format enum
219
+ *
220
+ * @private
221
+ * @param format - The audio format
222
+ * @param sampleRate - The sample rate in Hz
223
+ * @returns Azure audio format enum value
224
+ */
225
+ getAzureAudioFormat(format, sampleRate) {
226
+ const formatKey = `${format}_${sampleRate}`;
227
+ const formatMap = {
228
+ // MP3 formats
229
+ mp3_8000: sdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,
230
+ mp3_16000: sdk.SpeechSynthesisOutputFormat.Audio16Khz128KBitRateMonoMp3,
231
+ mp3_24000: sdk.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3,
232
+ mp3_48000: sdk.SpeechSynthesisOutputFormat.Audio48Khz192KBitRateMonoMp3,
233
+ // WAV formats
234
+ wav_8000: sdk.SpeechSynthesisOutputFormat.Riff8Khz16BitMonoPcm,
235
+ wav_16000: sdk.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,
236
+ wav_24000: sdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm,
237
+ wav_48000: sdk.SpeechSynthesisOutputFormat.Riff48Khz16BitMonoPcm,
238
+ // Opus formats
239
+ opus_8000: sdk.SpeechSynthesisOutputFormat.Ogg16Khz16BitMonoOpus,
240
+ opus_16000: sdk.SpeechSynthesisOutputFormat.Ogg16Khz16BitMonoOpus,
241
+ opus_24000: sdk.SpeechSynthesisOutputFormat.Ogg24Khz16BitMonoOpus,
242
+ opus_48000: sdk.SpeechSynthesisOutputFormat.Ogg48Khz16BitMonoOpus,
243
+ };
244
+ // Default formats if exact match not found
245
+ const defaultFormats = {
246
+ mp3: sdk.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3,
247
+ wav: sdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm,
248
+ opus: sdk.SpeechSynthesisOutputFormat.Ogg24Khz16BitMonoOpus,
249
+ aac: sdk.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3, // Fallback to MP3
250
+ flac: sdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm, // Fallback to WAV
251
+ };
252
+ return (formatMap[formatKey] ||
253
+ defaultFormats[format] ||
254
+ sdk.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3);
255
+ }
256
+ /**
257
+ * Generate SSML from plain text and options
258
+ *
259
+ * @private
260
+ * @param text - The input text
261
+ * @param voiceId - The voice identifier
262
+ * @param request - The synthesis request with options
263
+ * @returns SSML string
264
+ */
265
+ generateSSML(text, voiceId, request) {
266
+ // Extract language from voice ID (e.g., "en-US-JennyNeural" -> "en-US")
267
+ const language = voiceId.split('-').slice(0, 2).join('-');
268
+ // Extract provider options
269
+ const emotion = request.providerOptions?.emotion || null;
270
+ const style = request.providerOptions?.style || null;
271
+ const speed = request.audio?.speed || 1.0;
272
+ // Escape XML special characters
273
+ const escapedText = this.escapeXML(text);
274
+ // Build SSML
275
+ let ssml = `<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="${language}">`;
276
+ ssml += `<voice name="${voiceId}">`;
277
+ // Add style/emotion if provided (Azure-specific)
278
+ if (style || emotion) {
279
+ const expressAs = style || emotion;
280
+ ssml += `<mstts:express-as style="${expressAs}">`;
281
+ }
282
+ // Add prosody for speed control
283
+ const rateValue = this.speedToProsodyRate(speed);
284
+ ssml += `<prosody rate="${rateValue}">`;
285
+ // Add text
286
+ ssml += escapedText;
287
+ // Close prosody
288
+ ssml += `</prosody>`;
289
+ // Close express-as if used
290
+ if (style || emotion) {
291
+ ssml += `</mstts:express-as>`;
292
+ }
293
+ // Close voice and speak
294
+ ssml += `</voice>`;
295
+ ssml += `</speak>`;
296
+ return ssml;
297
+ }
298
+ /**
299
+ * Convert speed multiplier to SSML prosody rate value
300
+ *
301
+ * @private
302
+ * @param speed - Speed multiplier (0.5 - 2.0)
303
+ * @returns SSML rate value
304
+ */
305
+ speedToProsodyRate(speed) {
306
+ // Azure accepts percentage values: "50%" = half speed, "200%" = double speed
307
+ // Or relative values: "x-slow", "slow", "medium", "fast", "x-fast"
308
+ if (speed === 1.0) {
309
+ return 'medium';
310
+ }
311
+ // Convert to percentage (1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
312
+ const percentage = Math.round(speed * 100);
313
+ return `${percentage}%`;
314
+ }
315
+ /**
316
+ * Escape XML special characters
317
+ *
318
+ * @private
319
+ * @param text - The text to escape
320
+ * @returns Escaped text
321
+ */
322
+ escapeXML(text) {
323
+ return text
324
+ .replace(/&/g, '&amp;')
325
+ .replace(/</g, '&lt;')
326
+ .replace(/>/g, '&gt;')
327
+ .replace(/"/g, '&quot;')
328
+ .replace(/'/g, '&apos;');
329
+ }
330
+ /**
331
+ * Synthesize SSML using Azure Speech SDK
332
+ *
333
+ * @private
334
+ * @param synthesizer - The speech synthesizer
335
+ * @param ssml - The SSML to synthesize
336
+ * @returns Promise resolving to audio buffer
337
+ * @throws {InvalidVoiceError} If voice is not found
338
+ * @throws {SynthesisFailedError} If synthesis fails
339
+ */
340
+ async synthesizeSSML(synthesizer, ssml) {
341
+ return new Promise((resolve, reject) => {
342
+ synthesizer.speakSsmlAsync(ssml, (result) => {
343
+ if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
344
+ // Convert ArrayBuffer to Buffer
345
+ const audioBuffer = Buffer.from(result.audioData);
346
+ synthesizer.close();
347
+ resolve(audioBuffer);
348
+ }
349
+ else if (result.reason === sdk.ResultReason.Canceled) {
350
+ const cancellation = sdk.CancellationDetails.fromResult(result);
351
+ synthesizer.close();
352
+ // Check error type
353
+ if (cancellation.ErrorCode === sdk.CancellationErrorCode.AuthenticationFailure) {
354
+ reject(new base_tts_provider_1.InvalidConfigError(this.providerName, `Authentication failed: ${cancellation.errorDetails}`));
355
+ }
356
+ else if (cancellation.errorDetails?.includes('voice')) {
357
+ reject(new base_tts_provider_1.InvalidVoiceError(this.providerName, 'unknown', `Voice not found: ${cancellation.errorDetails}`));
358
+ }
359
+ else {
360
+ reject(new base_tts_provider_1.SynthesisFailedError(this.providerName, `Synthesis canceled: ${cancellation.errorDetails || 'Unknown error'}`));
361
+ }
362
+ }
363
+ else {
364
+ synthesizer.close();
365
+ reject(new base_tts_provider_1.SynthesisFailedError(this.providerName, `Unexpected result reason: ${sdk.ResultReason[result.reason]}`));
366
+ }
367
+ }, (error) => {
368
+ synthesizer.close();
369
+ reject(this.handleError(new Error(error), 'during Azure SDK call'));
370
+ });
371
+ });
372
+ }
373
+ }
374
+ exports.AzureProvider = AzureProvider;
375
+ //# sourceMappingURL=azure-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-provider.js","sourceRoot":"","sources":["../../../../../src/middleware/services/tts/providers/azure-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Base TTS Provider Abstract Class
3
+ *
4
+ * All TTS providers must extend this class and implement the abstract methods.
5
+ * This ensures consistency across all providers.
6
+ *
7
+ * @abstract
8
+ */
9
+ import type { TTSProvider, TTSSynthesizeRequest, TTSResponse, TTSErrorCode } from '../types';
10
+ /**
11
+ * Base error class for all TTS errors
12
+ */
13
+ export declare class TTSError extends Error {
14
+ readonly provider: string;
15
+ readonly code: TTSErrorCode;
16
+ readonly cause?: Error | undefined;
17
+ /**
18
+ * Creates a new TTS error
19
+ *
20
+ * @param provider - The provider that threw the error
21
+ * @param code - Error code for categorization
22
+ * @param message - Human-readable error message
23
+ * @param cause - Optional underlying error that caused this error
24
+ */
25
+ constructor(provider: string, code: TTSErrorCode, message: string, cause?: Error | undefined);
26
+ /**
27
+ * Returns a formatted error message with context
28
+ */
29
+ toString(): string;
30
+ }
31
+ /**
32
+ * Error thrown when TTS configuration is invalid or missing
33
+ */
34
+ export declare class InvalidConfigError extends TTSError {
35
+ constructor(provider: string, message: string, cause?: Error);
36
+ }
37
+ /**
38
+ * Error thrown when voice ID is invalid or not found
39
+ */
40
+ export declare class InvalidVoiceError extends TTSError {
41
+ constructor(provider: string, voiceId: string, message?: string, cause?: Error);
42
+ }
43
+ /**
44
+ * Error thrown when provider quota/rate limit is exceeded
45
+ */
46
+ export declare class QuotaExceededError extends TTSError {
47
+ constructor(provider: string, message?: string, cause?: Error);
48
+ }
49
+ /**
50
+ * Error thrown when provider service is unavailable
51
+ */
52
+ export declare class ProviderUnavailableError extends TTSError {
53
+ constructor(provider: string, message?: string, cause?: Error);
54
+ }
55
+ /**
56
+ * Error thrown when synthesis fails for unknown reasons
57
+ */
58
+ export declare class SynthesisFailedError extends TTSError {
59
+ constructor(provider: string, message: string, cause?: Error);
60
+ }
61
+ /**
62
+ * Error thrown when network operation fails
63
+ */
64
+ export declare class NetworkError extends TTSError {
65
+ constructor(provider: string, message: string, cause?: Error);
66
+ }
67
+ /**
68
+ * Abstract base class for all TTS providers
69
+ *
70
+ * @abstract
71
+ *
72
+ * @description All provider implementations must:
73
+ * - Extend this class
74
+ * - Implement the abstract synthesize() method
75
+ * - Call super() in constructor with the provider name
76
+ * - Use the provided error classes for consistent error handling
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * class AzureProvider extends BaseTTSProvider {
81
+ * constructor() {
82
+ * super(TTSProvider.AZURE);
83
+ * }
84
+ *
85
+ * async synthesize(text: string, voiceId: string, request: TTSSynthesizeRequest): Promise<TTSResponse> {
86
+ * this.validateConfig(request);
87
+ * // ... implementation
88
+ * }
89
+ * }
90
+ * ```
91
+ */
92
+ export declare abstract class BaseTTSProvider {
93
+ /**
94
+ * The provider name (e.g., 'azure', 'openai')
95
+ */
96
+ protected readonly providerName: TTSProvider;
97
+ /**
98
+ * Creates a new TTS provider
99
+ *
100
+ * @param providerName - The provider identifier
101
+ */
102
+ constructor(providerName: TTSProvider);
103
+ /**
104
+ * Synthesize text to speech
105
+ *
106
+ * @abstract
107
+ * @param text - The input text to synthesize
108
+ * @param voiceId - The voice identifier (provider-specific)
109
+ * @param request - The full synthesis request with options
110
+ * @returns Promise resolving to the synthesis response with audio buffer
111
+ * @throws {InvalidConfigError} If provider configuration is invalid
112
+ * @throws {InvalidVoiceError} If voice ID is not found
113
+ * @throws {QuotaExceededError} If provider quota is exceeded
114
+ * @throws {ProviderUnavailableError} If provider service is unavailable
115
+ * @throws {SynthesisFailedError} If synthesis fails for other reasons
116
+ */
117
+ abstract synthesize(text: string, voiceId: string, request: TTSSynthesizeRequest): Promise<TTSResponse>;
118
+ /**
119
+ * Get the provider name
120
+ *
121
+ * @returns The provider identifier
122
+ */
123
+ getProviderName(): TTSProvider;
124
+ /**
125
+ * Validate provider configuration
126
+ *
127
+ * @protected
128
+ * @param request - The synthesis request to validate
129
+ * @throws {InvalidConfigError} If configuration is invalid
130
+ *
131
+ * @description Subclasses should override this to validate provider-specific
132
+ * configuration (e.g., API keys, region settings)
133
+ */
134
+ protected validateConfig(request: TTSSynthesizeRequest): void;
135
+ /**
136
+ * Count characters in text for billing purposes
137
+ *
138
+ * @protected
139
+ * @param text - The input text to count
140
+ * @returns The number of characters (including spaces and punctuation)
141
+ *
142
+ * @description This is the base implementation that counts all characters.
143
+ * Providers that use SSML or have special character counting rules
144
+ * should override this method.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const count = this.countCharacters("Hello World!"); // returns 12
149
+ * ```
150
+ */
151
+ protected countCharacters(text: string): number;
152
+ /**
153
+ * Validate that a voice exists
154
+ *
155
+ * @protected
156
+ * @param _voiceId - The voice identifier to validate (unused in base implementation)
157
+ * @returns Promise resolving to true if voice exists
158
+ * @throws {InvalidVoiceError} If voice does not exist
159
+ *
160
+ * @description Base implementation always returns true. Providers should
161
+ * override this to validate voice IDs against their voice catalogs.
162
+ */
163
+ protected validateVoiceExists(_voiceId: string): Promise<boolean>;
164
+ /**
165
+ * Create a standardized error from a provider-specific error
166
+ *
167
+ * @protected
168
+ * @param error - The original error
169
+ * @param context - Additional context for debugging
170
+ * @returns A standardized TTS error
171
+ *
172
+ * @description Wraps provider-specific errors in our error classes
173
+ * for consistent error handling across providers.
174
+ */
175
+ protected handleError(error: Error, context?: string): TTSError;
176
+ /**
177
+ * Log a message using the pluggable logger
178
+ *
179
+ * @protected
180
+ * @param level - Log level
181
+ * @param message - Log message
182
+ * @param meta - Optional metadata
183
+ *
184
+ * @description Uses the global TTS logger which can be customized via setLogger().
185
+ * By default uses console logging, but can be replaced with any logger (Winston, Pino, etc.)
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * // In application code:
190
+ * import { setLogger, silentLogger } from '@loonylabs/tts-middleware';
191
+ *
192
+ * // Disable all logging
193
+ * setLogger(silentLogger);
194
+ *
195
+ * // Use custom logger
196
+ * setLogger({
197
+ * info: (msg, meta) => myLogger.info(msg, meta),
198
+ * // ...
199
+ * });
200
+ * ```
201
+ */
202
+ protected log(level: 'info' | 'warn' | 'error' | 'debug', message: string, meta?: Record<string, unknown>): void;
203
+ }
204
+ //# sourceMappingURL=base-tts-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-tts-provider.d.ts","sourceRoot":"","sources":["../../../../../src/middleware/services/tts/providers/base-tts-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,YAAY,EACb,MAAM,UAAU,CAAC;AAGlB;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAUf,QAAQ,EAAE,MAAM;aAChB,IAAI,EAAE,YAAY;aAElB,KAAK,CAAC,EAAE,KAAK;IAZ/B;;;;;;;OAOG;gBAEe,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,EAClC,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA;IAW/B;;OAEG;IACH,QAAQ,IAAI,MAAM;CAKnB;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI7D;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;gBAE3C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK;CAUhB;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAS9D;AAED;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ;gBACxC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAS9D;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI7D;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,QAAQ;gBAC5B,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,8BAAsB,eAAe;IACnC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC;IAE7C;;;;OAIG;gBACS,YAAY,EAAE,WAAW;IAIrC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,UAAU,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,WAAW,CAAC;IAEvB;;;;OAIG;IACI,eAAe,IAAI,WAAW;IAIrC;;;;;;;;;OASG;IACH,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAgB7D;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/C;;;;;;;;;;OAUG;cACa,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMvE;;;;;;;;;;OAUG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ;IAyD/D;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,SAAS,CAAC,GAAG,CACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAC1C,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,IAAI;CAGR"}