myvoicemaker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,469 @@
1
+ 'use strict';
2
+
3
+ var promises = require('fs/promises');
4
+ var path = require('path');
5
+
6
+ // src/http/client.ts
7
+
8
+ // src/errors/index.ts
9
+ var VoiceMakerError = class extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = "VoiceMakerError";
13
+ Object.setPrototypeOf(this, new.target.prototype);
14
+ }
15
+ };
16
+ var VoiceMakerAPIError = class extends VoiceMakerError {
17
+ status;
18
+ error;
19
+ detail;
20
+ requestId;
21
+ issues;
22
+ constructor(status, body, message) {
23
+ super(message ?? body.detail ?? body.error);
24
+ this.name = "VoiceMakerAPIError";
25
+ this.status = status;
26
+ this.error = body.error;
27
+ this.detail = body.detail;
28
+ this.requestId = body.requestId;
29
+ this.issues = body.issues;
30
+ Object.setPrototypeOf(this, new.target.prototype);
31
+ }
32
+ };
33
+ var AuthenticationError = class extends VoiceMakerAPIError {
34
+ constructor(body) {
35
+ super(401, body);
36
+ this.name = "AuthenticationError";
37
+ Object.setPrototypeOf(this, new.target.prototype);
38
+ }
39
+ };
40
+ var InsufficientCreditsError = class extends VoiceMakerAPIError {
41
+ constructor(body) {
42
+ super(402, body);
43
+ this.name = "InsufficientCreditsError";
44
+ Object.setPrototypeOf(this, new.target.prototype);
45
+ }
46
+ };
47
+ var PermissionError = class extends VoiceMakerAPIError {
48
+ constructor(body) {
49
+ super(403, body);
50
+ this.name = "PermissionError";
51
+ Object.setPrototypeOf(this, new.target.prototype);
52
+ }
53
+ };
54
+ var NotFoundError = class extends VoiceMakerAPIError {
55
+ constructor(body) {
56
+ super(404, body);
57
+ this.name = "NotFoundError";
58
+ Object.setPrototypeOf(this, new.target.prototype);
59
+ }
60
+ };
61
+ var FileSizeLimitError = class extends VoiceMakerAPIError {
62
+ constructor(body) {
63
+ super(413, body);
64
+ this.name = "FileSizeLimitError";
65
+ Object.setPrototypeOf(this, new.target.prototype);
66
+ }
67
+ };
68
+ var UnsupportedMediaTypeError = class extends VoiceMakerAPIError {
69
+ constructor(body) {
70
+ super(415, body);
71
+ this.name = "UnsupportedMediaTypeError";
72
+ Object.setPrototypeOf(this, new.target.prototype);
73
+ }
74
+ };
75
+ var ValidationError = class extends VoiceMakerAPIError {
76
+ constructor(body) {
77
+ super(422, body);
78
+ this.name = "ValidationError";
79
+ Object.setPrototypeOf(this, new.target.prototype);
80
+ }
81
+ };
82
+ var RateLimitError = class extends VoiceMakerAPIError {
83
+ retryAfter;
84
+ constructor(body, retryAfter) {
85
+ super(429, body);
86
+ this.name = "RateLimitError";
87
+ this.retryAfter = retryAfter;
88
+ Object.setPrototypeOf(this, new.target.prototype);
89
+ }
90
+ };
91
+ var ServerError = class extends VoiceMakerAPIError {
92
+ constructor(status, body) {
93
+ super(status, body);
94
+ this.name = "ServerError";
95
+ Object.setPrototypeOf(this, new.target.prototype);
96
+ }
97
+ };
98
+ var TimeoutError = class extends VoiceMakerError {
99
+ jobId;
100
+ timeoutMs;
101
+ constructor(jobId, timeoutMs) {
102
+ super(
103
+ `Job '${jobId}' did not complete within ${timeoutMs}ms`
104
+ );
105
+ this.name = "TimeoutError";
106
+ this.jobId = jobId;
107
+ this.timeoutMs = timeoutMs;
108
+ Object.setPrototypeOf(this, new.target.prototype);
109
+ }
110
+ };
111
+ function createApiError(status, body, retryAfterHeader) {
112
+ const retryAfter = retryAfterHeader != null ? Number(retryAfterHeader) : void 0;
113
+ switch (status) {
114
+ case 401:
115
+ return new AuthenticationError(body);
116
+ case 402:
117
+ return new InsufficientCreditsError(body);
118
+ case 403:
119
+ return new PermissionError(body);
120
+ case 404:
121
+ return new NotFoundError(body);
122
+ case 413:
123
+ return new FileSizeLimitError(body);
124
+ case 415:
125
+ return new UnsupportedMediaTypeError(body);
126
+ case 422:
127
+ return new ValidationError(body);
128
+ case 429:
129
+ return new RateLimitError(body, retryAfter);
130
+ default:
131
+ return new ServerError(status, body);
132
+ }
133
+ }
134
+
135
+ // src/http/client.ts
136
+ var HttpClient = class {
137
+ apiKey;
138
+ baseUrl;
139
+ timeoutMs;
140
+ constructor(config) {
141
+ this.apiKey = config.apiKey;
142
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
143
+ this.timeoutMs = config.timeoutMs;
144
+ }
145
+ async get(path, query) {
146
+ const url = this.buildUrl(path, query);
147
+ const response = await this.fetchWithTimeout(url, {
148
+ method: "GET",
149
+ headers: this.authHeaders()
150
+ });
151
+ return this.parseResponse(response);
152
+ }
153
+ async post(path, body) {
154
+ const url = this.buildUrl(path);
155
+ const response = await this.fetchWithTimeout(url, {
156
+ method: "POST",
157
+ headers: { ...this.authHeaders(), "Content-Type": "application/json" },
158
+ body: JSON.stringify(body)
159
+ });
160
+ return this.parseResponse(response);
161
+ }
162
+ async postMultipart(path$1, filePath, fields) {
163
+ const url = this.buildUrl(path$1);
164
+ const form = new FormData();
165
+ const fileBuffer = await promises.readFile(filePath);
166
+ const fileName = path.basename(filePath);
167
+ const blob = new Blob([fileBuffer]);
168
+ form.append("audio", blob, fileName);
169
+ for (const [key, value] of Object.entries(fields)) {
170
+ if (value !== void 0) {
171
+ form.append(key, value);
172
+ }
173
+ }
174
+ const response = await this.fetchWithTimeout(url, {
175
+ method: "POST",
176
+ headers: this.authHeaders(),
177
+ body: form
178
+ });
179
+ return this.parseResponse(response);
180
+ }
181
+ buildUrl(path, query) {
182
+ const url = new URL(`${this.baseUrl}${path}`);
183
+ if (query) {
184
+ for (const [key, value] of Object.entries(query)) {
185
+ if (value !== void 0) {
186
+ url.searchParams.set(key, String(value));
187
+ }
188
+ }
189
+ }
190
+ return url.toString();
191
+ }
192
+ authHeaders() {
193
+ return { Authorization: `Bearer ${this.apiKey}` };
194
+ }
195
+ async fetchWithTimeout(url, init) {
196
+ const controller = new AbortController();
197
+ const timer = setTimeout(
198
+ () => controller.abort(),
199
+ this.timeoutMs
200
+ );
201
+ try {
202
+ return await fetch(url, { ...init, signal: controller.signal });
203
+ } finally {
204
+ clearTimeout(timer);
205
+ }
206
+ }
207
+ parseRateLimit(response) {
208
+ const limit = response.headers.get("X-RateLimit-Limit");
209
+ const remaining = response.headers.get("X-RateLimit-Remaining");
210
+ const reset = response.headers.get("X-RateLimit-Reset");
211
+ if (limit === null || remaining === null || reset === null) {
212
+ return void 0;
213
+ }
214
+ return {
215
+ limit: Number(limit),
216
+ remaining: Number(remaining),
217
+ reset: Number(reset)
218
+ };
219
+ }
220
+ async parseResponse(response) {
221
+ const requestId = response.headers.get("X-Request-Id") ?? void 0;
222
+ const rateLimit = this.parseRateLimit(response);
223
+ if (!response.ok) {
224
+ let body;
225
+ try {
226
+ body = await response.json();
227
+ } catch {
228
+ body = {
229
+ error: "Unknown error",
230
+ detail: `HTTP ${response.status}: ${response.statusText}`
231
+ };
232
+ }
233
+ const retryAfter = response.headers.get("Retry-After");
234
+ throw createApiError(response.status, body, retryAfter);
235
+ }
236
+ const data = await response.json();
237
+ return { data, requestId, rateLimit };
238
+ }
239
+ };
240
+
241
+ // src/modules/base.ts
242
+ var BaseModule = class {
243
+ http;
244
+ constructor(http) {
245
+ this.http = http;
246
+ }
247
+ };
248
+
249
+ // src/utils/poll.ts
250
+ var DEFAULT_INTERVAL_MS = 2e3;
251
+ var DEFAULT_TIMEOUT_MS = 12e4;
252
+ async function poll(jobId, fn, isDone, options) {
253
+ const intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;
254
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
255
+ const deadline = Date.now() + timeoutMs;
256
+ while (true) {
257
+ const result = await fn();
258
+ if (isDone(result)) {
259
+ return result;
260
+ }
261
+ if (Date.now() >= deadline) {
262
+ throw new TimeoutError(jobId, timeoutMs);
263
+ }
264
+ await sleep(intervalMs);
265
+ }
266
+ }
267
+ function sleep(ms) {
268
+ return new Promise((resolve) => setTimeout(resolve, ms));
269
+ }
270
+
271
+ // src/modules/asr.ts
272
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed"]);
273
+ var ASRModule = class extends BaseModule {
274
+ async transcribe(params) {
275
+ const body = { audio: params.audio };
276
+ if (params.language !== void 0) body["language"] = params.language;
277
+ if (params.webhookUrl !== void 0) body["webhookUrl"] = params.webhookUrl;
278
+ const { data } = await this.http.post(
279
+ "/dev/v1/transcribe",
280
+ body
281
+ );
282
+ return data;
283
+ }
284
+ async transcribeFile(filePath, params) {
285
+ const fields = {
286
+ language: params?.language,
287
+ webhook_url: params?.webhookUrl
288
+ };
289
+ const { data } = await this.http.postMultipart(
290
+ "/dev/v1/transcribe",
291
+ filePath,
292
+ fields
293
+ );
294
+ return data;
295
+ }
296
+ async getResult(jobId) {
297
+ const { data } = await this.http.get(
298
+ `/dev/v1/transcribe/${jobId}`
299
+ );
300
+ return data;
301
+ }
302
+ async list(params) {
303
+ const query = {};
304
+ if (params?.limit !== void 0) query["limit"] = params.limit;
305
+ if (params?.cursor !== void 0) query["cursor"] = params.cursor;
306
+ if (params?.status !== void 0) query["status"] = params.status;
307
+ const { data } = await this.http.get(
308
+ "/dev/v1/transcriptions",
309
+ query
310
+ );
311
+ return data;
312
+ }
313
+ async poll(jobId, options) {
314
+ return poll(
315
+ jobId,
316
+ () => this.getResult(jobId),
317
+ (result) => TERMINAL_STATUSES.has(result.status),
318
+ options
319
+ );
320
+ }
321
+ };
322
+
323
+ // src/modules/tts.ts
324
+ var TTSModule = class extends BaseModule {
325
+ async listVoices(params) {
326
+ const query = {};
327
+ if (params?.language !== void 0) {
328
+ query["language"] = params.language;
329
+ }
330
+ const { data } = await this.http.get(
331
+ "/dev/v1/tts/voices",
332
+ query
333
+ );
334
+ return data;
335
+ }
336
+ async generate(params) {
337
+ const body = {
338
+ text: params.text,
339
+ voice_id: params.voice_id,
340
+ language: params.language
341
+ };
342
+ if (params.speed !== void 0) body["speed"] = params.speed;
343
+ if (params.output_format !== void 0) {
344
+ body["output_format"] = params.output_format;
345
+ }
346
+ const { data } = await this.http.post(
347
+ "/dev/v1/tts/generate",
348
+ body
349
+ );
350
+ return data;
351
+ }
352
+ };
353
+
354
+ // src/modules/animate.ts
355
+ var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed"]);
356
+ var AnimateModule = class extends BaseModule {
357
+ async generate(params) {
358
+ const body = {
359
+ image_url: params.image_url,
360
+ audio_url: params.audio_url
361
+ };
362
+ if (params.output_format !== void 0) {
363
+ body["output_format"] = params.output_format;
364
+ }
365
+ const { data } = await this.http.post(
366
+ "/dev/v1/animate/generate",
367
+ body
368
+ );
369
+ return data;
370
+ }
371
+ async getResult(jobId) {
372
+ const { data } = await this.http.get(
373
+ `/dev/v1/animate/${jobId}`
374
+ );
375
+ return data;
376
+ }
377
+ async poll(jobId, options) {
378
+ return poll(
379
+ jobId,
380
+ () => this.getResult(jobId),
381
+ (result) => TERMINAL_STATUSES2.has(result.status),
382
+ options
383
+ );
384
+ }
385
+ };
386
+
387
+ // src/modules/explain.ts
388
+ var ExplainModule = class extends BaseModule {
389
+ async process(params) {
390
+ const body = {
391
+ text: params.text,
392
+ language: params.language,
393
+ action: params.action
394
+ };
395
+ if (params.target_language !== void 0) {
396
+ body["target_language"] = params.target_language;
397
+ }
398
+ if (params.max_tokens !== void 0) {
399
+ body["max_tokens"] = params.max_tokens;
400
+ }
401
+ const { data } = await this.http.post(
402
+ "/dev/v1/explain",
403
+ body
404
+ );
405
+ return data;
406
+ }
407
+ };
408
+
409
+ // src/modules/usage.ts
410
+ var UsageModule = class extends BaseModule {
411
+ async getBalance() {
412
+ const { data } = await this.http.get("/dev/v1/usage");
413
+ return data;
414
+ }
415
+ async getBreakdown(params) {
416
+ const query = {
417
+ start_date: params.start_date,
418
+ end_date: params.end_date
419
+ };
420
+ if (params.module !== void 0) query["module"] = params.module;
421
+ const { data } = await this.http.get(
422
+ "/dev/v1/usage/breakdown",
423
+ query
424
+ );
425
+ return data;
426
+ }
427
+ };
428
+
429
+ // src/client.ts
430
+ var DEFAULT_BASE_URL = "https://api.myvoicemaker.ai";
431
+ var DEFAULT_TIMEOUT_MS2 = 3e4;
432
+ var VoiceMaker = class {
433
+ tts;
434
+ asr;
435
+ animate;
436
+ explain;
437
+ usage;
438
+ constructor(config) {
439
+ if (!config.apiKey) {
440
+ throw new Error("VoiceMaker: apiKey is required");
441
+ }
442
+ const http = new HttpClient({
443
+ apiKey: config.apiKey,
444
+ baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
445
+ timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS2
446
+ });
447
+ this.tts = new TTSModule(http);
448
+ this.asr = new ASRModule(http);
449
+ this.animate = new AnimateModule(http);
450
+ this.explain = new ExplainModule(http);
451
+ this.usage = new UsageModule(http);
452
+ }
453
+ };
454
+
455
+ exports.AuthenticationError = AuthenticationError;
456
+ exports.FileSizeLimitError = FileSizeLimitError;
457
+ exports.InsufficientCreditsError = InsufficientCreditsError;
458
+ exports.NotFoundError = NotFoundError;
459
+ exports.PermissionError = PermissionError;
460
+ exports.RateLimitError = RateLimitError;
461
+ exports.ServerError = ServerError;
462
+ exports.TimeoutError = TimeoutError;
463
+ exports.UnsupportedMediaTypeError = UnsupportedMediaTypeError;
464
+ exports.ValidationError = ValidationError;
465
+ exports.VoiceMaker = VoiceMaker;
466
+ exports.VoiceMakerAPIError = VoiceMakerAPIError;
467
+ exports.VoiceMakerError = VoiceMakerError;
468
+ //# sourceMappingURL=index.cjs.map
469
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/http/client.ts","../src/modules/base.ts","../src/utils/poll.ts","../src/modules/asr.ts","../src/modules/tts.ts","../src/modules/animate.ts","../src/modules/explain.ts","../src/modules/usage.ts","../src/client.ts"],"names":["path","readFile","basename","TERMINAL_STATUSES","DEFAULT_TIMEOUT_MS"],"mappings":";;;;;;;;AAaO,IAAM,eAAA,GAAN,cAA8B,KAAA,CAAM;AAAA,EACzC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,eAAA,CAAgB;AAAA,EAC7C,MAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EAET,WAAA,CACE,MAAA,EACA,IAAA,EACA,OAAA,EACA;AACA,IAAA,KAAA,CAAM,OAAA,IAAW,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,KAAK,CAAA;AAC1C,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,YAAY,IAAA,CAAK,SAAA;AACtB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,kBAAA,CAAmB;AAAA,EAC1D,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,wBAAA,GAAN,cAAuC,kBAAA,CAAmB;AAAA,EAC/D,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,0BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,kBAAA,CAAmB;AAAA,EACtD,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,aAAA,GAAN,cAA4B,kBAAA,CAAmB;AAAA,EACpD,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,kBAAA,CAAmB;AAAA,EACzD,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,yBAAA,GAAN,cAAwC,kBAAA,CAAmB;AAAA,EAChE,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,2BAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,kBAAA,CAAmB;AAAA,EACtD,YAAY,IAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,iBAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,cAAA,GAAN,cAA6B,kBAAA,CAAmB;AAAA,EAC5C,UAAA;AAAA,EAET,WAAA,CAAY,MAAoB,UAAA,EAAqB;AACnD,IAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,WAAA,GAAN,cAA0B,kBAAA,CAAmB;AAAA,EAClD,WAAA,CAAY,QAAgB,IAAA,EAAoB;AAC9C,IAAA,KAAA,CAAM,QAAQ,IAAI,CAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,IAAM,YAAA,GAAN,cAA2B,eAAA,CAAgB;AAAA,EACvC,KAAA;AAAA,EACA,SAAA;AAAA,EAET,WAAA,CAAY,OAAe,SAAA,EAAmB;AAC5C,IAAA,KAAA;AAAA,MACE,CAAA,KAAA,EAAQ,KAAK,CAAA,0BAAA,EAA6B,SAAS,CAAA,EAAA;AAAA,KACrD;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AACF;AAEO,SAAS,cAAA,CACd,MAAA,EACA,IAAA,EACA,gBAAA,EACoB;AACpB,EAAA,MAAM,UAAA,GAAa,gBAAA,IAAoB,IAAA,GACnC,MAAA,CAAO,gBAAgB,CAAA,GACvB,MAAA;AAEJ,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,oBAAoB,IAAI,CAAA;AAAA,IACrC,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,yBAAyB,IAAI,CAAA;AAAA,IAC1C,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,gBAAgB,IAAI,CAAA;AAAA,IACjC,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,cAAc,IAAI,CAAA;AAAA,IAC/B,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,mBAAmB,IAAI,CAAA;AAAA,IACpC,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,0BAA0B,IAAI,CAAA;AAAA,IAC3C,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,gBAAgB,IAAI,CAAA;AAAA,IACjC,KAAK,GAAA;AACH,MAAA,OAAO,IAAI,cAAA,CAAe,IAAA,EAAM,UAAU,CAAA;AAAA,IAC5C;AACE,MAAA,OAAO,IAAI,WAAA,CAAY,MAAA,EAAQ,IAAI,CAAA;AAAA;AAEzC;;;ACxJO,IAAM,aAAN,MAAiB;AAAA,EACL,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EAEjB,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC/C,IAAA,IAAA,CAAK,YAAY,MAAA,CAAO,SAAA;AAAA,EAC1B;AAAA,EAEA,MAAM,GAAA,CACJ,IAAA,EACA,KAAA,EACyB;AACzB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AACrC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,gBAAA,CAAiB,GAAA,EAAK;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS,KAAK,WAAA;AAAY,KAC3B,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,cAAiB,QAAQ,CAAA;AAAA,EACvC;AAAA,EAEA,MAAM,IAAA,CAAQ,IAAA,EAAc,IAAA,EAAwC;AAClE,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,gBAAA,CAAiB,GAAA,EAAK;AAAA,MAChD,MAAA,EAAQ,MAAA;AAAA,MACR,SAAS,EAAE,GAAG,KAAK,WAAA,EAAY,EAAG,gBAAgB,kBAAA,EAAmB;AAAA,MACrE,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,cAAiB,QAAQ,CAAA;AAAA,EACvC;AAAA,EAEA,MAAM,aAAA,CACJA,MAAA,EACA,QAAA,EACA,MAAA,EACyB;AACzB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAASA,MAAI,CAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,IAAI,QAAA,EAAS;AAE1B,IAAA,MAAM,UAAA,GAAa,MAAMC,iBAAA,CAAS,QAAQ,CAAA;AAC1C,IAAA,MAAM,QAAA,GAAWC,cAAS,QAAQ,CAAA;AAClC,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,UAAU,CAAC,CAAA;AAClC,IAAA,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,IAAA,EAAM,QAAQ,CAAA;AAEnC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,MACxB;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,gBAAA,CAAiB,GAAA,EAAK;AAAA,MAChD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,KAAK,WAAA,EAAY;AAAA,MAC1B,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,cAAiB,QAAQ,CAAA;AAAA,EACvC;AAAA,EAEQ,QAAA,CAAS,MAAc,KAAA,EAA6B;AAC1D,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,CAAA,EAAG,KAAK,OAAO,CAAA,EAAG,IAAI,CAAA,CAAE,CAAA;AAC5C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,QAAA,IAAI,UAAU,MAAA,EAAW;AACvB,UAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA,EAEQ,WAAA,GAAsC;AAC5C,IAAA,OAAO,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA,EAAG;AAAA,EAClD;AAAA,EAEA,MAAc,gBAAA,CACZ,GAAA,EACA,IAAA,EACmB;AACnB,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,KAAA,GAAQ,UAAA;AAAA,MACZ,MAAM,WAAW,KAAA,EAAM;AAAA,MACvB,IAAA,CAAK;AAAA,KACP;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,MAAM,GAAA,EAAK,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,CAAA;AAAA,IAChE,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,eAAe,QAAA,EAAkD;AACvE,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AACtD,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,uBAAuB,CAAA;AAC9D,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAEtD,IAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,SAAA,KAAc,IAAA,IAAQ,UAAU,IAAA,EAAM;AAC1D,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAO,KAAK,CAAA;AAAA,MACnB,SAAA,EAAW,OAAO,SAAS,CAAA;AAAA,MAC3B,KAAA,EAAO,OAAO,KAAK;AAAA,KACrB;AAAA,EACF;AAAA,EAEA,MAAc,cAAiB,QAAA,EAA6C;AAC1E,IAAA,MAAM,SAAA,GACJ,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA;AAC1C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,cAAA,CAAe,QAAQ,CAAA;AAE9C,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI;AACF,QAAA,IAAA,GAAQ,MAAM,SAAS,IAAA,EAAK;AAAA,MAC9B,CAAA,CAAA,MAAQ;AACN,QAAA,IAAA,GAAO;AAAA,UACL,KAAA,EAAO,eAAA;AAAA,UACP,QAAQ,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,EAAA,EAAK,SAAS,UAAU,CAAA;AAAA,SACzD;AAAA,MACF;AACA,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AACrD,MAAA,MAAM,cAAA,CAAe,QAAA,CAAS,MAAA,EAAQ,IAAA,EAAM,UAAU,CAAA;AAAA,IACxD;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,SAAA,EAAU;AAAA,EACtC;AACF,CAAA;;;AC5IO,IAAe,aAAf,MAA0B;AAAA,EACZ,IAAA;AAAA,EAEnB,YAAY,IAAA,EAAkB;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF,CAAA;;;ACNA,IAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAM,kBAAA,GAAqB,IAAA;AAE3B,eAAsB,IAAA,CACpB,KAAA,EACA,EAAA,EACA,MAAA,EACA,OAAA,EACY;AACZ,EAAA,MAAM,UAAA,GAAa,SAAS,UAAA,IAAc,mBAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,kBAAA;AACxC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAE9B,EAAA,OAAO,IAAA,EAAM;AACX,IAAA,MAAM,MAAA,GAAS,MAAM,EAAA,EAAG;AACxB,IAAA,IAAI,MAAA,CAAO,MAAM,CAAA,EAAG;AAClB,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,QAAA,EAAU;AAC1B,MAAA,MAAM,IAAI,YAAA,CAAa,KAAA,EAAO,SAAS,CAAA;AAAA,IACzC;AAEA,IAAA,MAAM,MAAM,UAAU,CAAA;AAAA,EACxB;AACF;AAEA,SAAS,MAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;;;ACpBA,IAAM,oCAAoB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,QAAQ,CAAC,CAAA;AAElD,IAAM,SAAA,GAAN,cAAwB,UAAA,CAAW;AAAA,EACxC,MAAM,WAAW,MAAA,EAAwD;AACvE,IAAA,MAAM,IAAA,GAAgC,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM;AAC5D,IAAA,IAAI,OAAO,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,UAAU,IAAI,MAAA,CAAO,QAAA;AAC7D,IAAA,IAAI,OAAO,UAAA,KAAe,MAAA,EAAW,IAAA,CAAK,YAAY,IAAI,MAAA,CAAO,UAAA;AAEjE,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,IAAA;AAAA,MAC/B,oBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,cAAA,CACJ,QAAA,EACA,MAAA,EAC2B;AAC3B,IAAA,MAAM,MAAA,GAA6C;AAAA,MACjD,UAAU,MAAA,EAAQ,QAAA;AAAA,MAClB,aAAa,MAAA,EAAQ;AAAA,KACvB;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,aAAA;AAAA,MAC/B,oBAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,KAAA,EAA0C;AACxD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MAC/B,sBAAsB,KAAK,CAAA;AAAA,KAC7B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,KACJ,MAAA,EAC8C;AAC9C,IAAA,MAAM,QAAqB,EAAC;AAC5B,IAAA,IAAI,QAAQ,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,OAAO,IAAI,MAAA,CAAO,KAAA;AACzD,IAAA,IAAI,QAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,QAAQ,IAAI,MAAA,CAAO,MAAA;AAC3D,IAAA,IAAI,QAAQ,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,QAAQ,IAAI,MAAA,CAAO,MAAA;AAE3D,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MAC/B,wBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAA,CACJ,KAAA,EACA,OAAA,EAC2B;AAC3B,IAAA,OAAO,IAAA;AAAA,MACL,KAAA;AAAA,MACA,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,MAC1B,CAAC,MAAA,KAAW,iBAAA,CAAkB,GAAA,CAAI,OAAO,MAAM,CAAA;AAAA,MAC/C;AAAA,KACF;AAAA,EACF;AACF,CAAA;;;ACnEO,IAAM,SAAA,GAAN,cAAwB,UAAA,CAAW;AAAA,EACxC,MAAM,WAAW,MAAA,EAAuD;AACtE,IAAA,MAAM,QAAqB,EAAC;AAC5B,IAAA,IAAI,MAAA,EAAQ,aAAa,MAAA,EAAW;AAClC,MAAA,KAAA,CAAM,UAAU,IAAI,MAAA,CAAO,QAAA;AAAA,IAC7B;AACA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MAC/B,oBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,MAAA,EAAyD;AACtE,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,UAAU,MAAA,CAAO;AAAA,KACnB;AACA,IAAA,IAAI,OAAO,KAAA,KAAU,MAAA,EAAW,IAAA,CAAK,OAAO,IAAI,MAAA,CAAO,KAAA;AACvD,IAAA,IAAI,MAAA,CAAO,kBAAkB,MAAA,EAAW;AACtC,MAAA,IAAA,CAAK,eAAe,IAAI,MAAA,CAAO,aAAA;AAAA,IACjC;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,IAAA;AAAA,MAC/B,sBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AC9BA,IAAMC,qCAAoB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,QAAQ,CAAC,CAAA;AAElD,IAAM,aAAA,GAAN,cAA4B,UAAA,CAAW;AAAA,EAC5C,MAAM,SAAS,MAAA,EAA4D;AACzE,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,WAAW,MAAA,CAAO;AAAA,KACpB;AACA,IAAA,IAAI,MAAA,CAAO,kBAAkB,MAAA,EAAW;AACtC,MAAA,IAAA,CAAK,eAAe,IAAI,MAAA,CAAO,aAAA;AAAA,IACjC;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,IAAA;AAAA,MAC/B,0BAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,KAAA,EAA+C;AAC7D,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MAC/B,mBAAmB,KAAK,CAAA;AAAA,KAC1B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,IAAA,CACJ,KAAA,EACA,OAAA,EACgC;AAChC,IAAA,OAAO,IAAA;AAAA,MACL,KAAA;AAAA,MACA,MAAM,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAA,MAC1B,CAAC,MAAA,KAAWA,kBAAAA,CAAkB,GAAA,CAAI,OAAO,MAAM,CAAA;AAAA,MAC/C;AAAA,KACF;AAAA,EACF;AACF,CAAA;;;AC3CO,IAAM,aAAA,GAAN,cAA4B,UAAA,CAAW;AAAA,EAC5C,MAAM,QAAQ,MAAA,EAAiD;AAC7D,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,UAAU,MAAA,CAAO,QAAA;AAAA,MACjB,QAAQ,MAAA,CAAO;AAAA,KACjB;AACA,IAAA,IAAI,MAAA,CAAO,oBAAoB,MAAA,EAAW;AACxC,MAAA,IAAA,CAAK,iBAAiB,IAAI,MAAA,CAAO,eAAA;AAAA,IACnC;AACA,IAAA,IAAI,MAAA,CAAO,eAAe,MAAA,EAAW;AACnC,MAAA,IAAA,CAAK,YAAY,IAAI,MAAA,CAAO,UAAA;AAAA,IAC9B;AAEA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,IAAA;AAAA,MAC/B,iBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;ACfO,IAAM,WAAA,GAAN,cAA0B,UAAA,CAAW;AAAA,EAC1C,MAAM,UAAA,GAA4C;AAChD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,IAAA,CAAK,IAA0B,eAAe,CAAA;AAC1E,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,aACJ,MAAA,EACiC;AACjC,IAAA,MAAM,KAAA,GAAqB;AAAA,MACzB,YAAY,MAAA,CAAO,UAAA;AAAA,MACnB,UAAU,MAAA,CAAO;AAAA,KACnB;AACA,IAAA,IAAI,OAAO,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,QAAQ,IAAI,MAAA,CAAO,MAAA;AAE1D,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MAC/B,yBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AChBA,IAAM,gBAAA,GAAmB,6BAAA;AACzB,IAAMC,mBAAAA,GAAqB,GAAA;AAEpB,IAAM,aAAN,MAAiB;AAAA,EACb,GAAA;AAAA,EACA,GAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EAET,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,IAClD;AAEA,IAAA,MAAM,IAAA,GAAO,IAAI,UAAA,CAAW;AAAA,MAC1B,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAA,EAAS,OAAO,OAAA,IAAW,gBAAA;AAAA,MAC3B,SAAA,EAAW,OAAO,SAAA,IAAaA;AAAA,KAChC,CAAA;AAED,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,SAAA,CAAU,IAAI,CAAA;AAC7B,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,SAAA,CAAU,IAAI,CAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,aAAA,CAAc,IAAI,CAAA;AACrC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,aAAA,CAAc,IAAI,CAAA;AACrC,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,WAAA,CAAY,IAAI,CAAA;AAAA,EACnC;AACF","file":"index.cjs","sourcesContent":["export interface ApiErrorIssue {\n field: string;\n code: string;\n message: string;\n}\n\nexport interface ApiErrorBody {\n error: string;\n detail: string;\n requestId?: string;\n issues?: ApiErrorIssue[];\n}\n\nexport class VoiceMakerError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VoiceMakerError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class VoiceMakerAPIError extends VoiceMakerError {\n readonly status: number;\n readonly error: string;\n readonly detail: string;\n readonly requestId: string | undefined;\n readonly issues: ApiErrorIssue[] | undefined;\n\n constructor(\n status: number,\n body: ApiErrorBody,\n message?: string,\n ) {\n super(message ?? body.detail ?? body.error);\n this.name = \"VoiceMakerAPIError\";\n this.status = status;\n this.error = body.error;\n this.detail = body.detail;\n this.requestId = body.requestId;\n this.issues = body.issues;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(401, body);\n this.name = \"AuthenticationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class InsufficientCreditsError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(402, body);\n this.name = \"InsufficientCreditsError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class PermissionError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(403, body);\n this.name = \"PermissionError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class NotFoundError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(404, body);\n this.name = \"NotFoundError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class FileSizeLimitError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(413, body);\n this.name = \"FileSizeLimitError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class UnsupportedMediaTypeError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(415, body);\n this.name = \"UnsupportedMediaTypeError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class ValidationError extends VoiceMakerAPIError {\n constructor(body: ApiErrorBody) {\n super(422, body);\n this.name = \"ValidationError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class RateLimitError extends VoiceMakerAPIError {\n readonly retryAfter: number | undefined;\n\n constructor(body: ApiErrorBody, retryAfter?: number) {\n super(429, body);\n this.name = \"RateLimitError\";\n this.retryAfter = retryAfter;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class ServerError extends VoiceMakerAPIError {\n constructor(status: number, body: ApiErrorBody) {\n super(status, body);\n this.name = \"ServerError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class TimeoutError extends VoiceMakerError {\n readonly jobId: string;\n readonly timeoutMs: number;\n\n constructor(jobId: string, timeoutMs: number) {\n super(\n `Job '${jobId}' did not complete within ${timeoutMs}ms`,\n );\n this.name = \"TimeoutError\";\n this.jobId = jobId;\n this.timeoutMs = timeoutMs;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport function createApiError(\n status: number,\n body: ApiErrorBody,\n retryAfterHeader?: string | null,\n): VoiceMakerAPIError {\n const retryAfter = retryAfterHeader != null\n ? Number(retryAfterHeader)\n : undefined;\n\n switch (status) {\n case 401:\n return new AuthenticationError(body);\n case 402:\n return new InsufficientCreditsError(body);\n case 403:\n return new PermissionError(body);\n case 404:\n return new NotFoundError(body);\n case 413:\n return new FileSizeLimitError(body);\n case 415:\n return new UnsupportedMediaTypeError(body);\n case 422:\n return new ValidationError(body);\n case 429:\n return new RateLimitError(body, retryAfter);\n default:\n return new ServerError(status, body);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { createApiError, type ApiErrorBody } from \"../errors/index.js\";\nimport type { ApiResponse, QueryParams, RateLimitHeaders } from \"./types.js\";\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl: string;\n timeoutMs: number;\n}\n\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n this.timeoutMs = config.timeoutMs;\n }\n\n async get<T>(\n path: string,\n query?: QueryParams,\n ): Promise<ApiResponse<T>> {\n const url = this.buildUrl(path, query);\n const response = await this.fetchWithTimeout(url, {\n method: \"GET\",\n headers: this.authHeaders(),\n });\n return this.parseResponse<T>(response);\n }\n\n async post<T>(path: string, body: unknown): Promise<ApiResponse<T>> {\n const url = this.buildUrl(path);\n const response = await this.fetchWithTimeout(url, {\n method: \"POST\",\n headers: { ...this.authHeaders(), \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseResponse<T>(response);\n }\n\n async postMultipart<T>(\n path: string,\n filePath: string,\n fields: Record<string, string | undefined>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildUrl(path);\n const form = new FormData();\n\n const fileBuffer = await readFile(filePath);\n const fileName = basename(filePath);\n const blob = new Blob([fileBuffer]);\n form.append(\"audio\", blob, fileName);\n\n for (const [key, value] of Object.entries(fields)) {\n if (value !== undefined) {\n form.append(key, value);\n }\n }\n\n const response = await this.fetchWithTimeout(url, {\n method: \"POST\",\n headers: this.authHeaders(),\n body: form,\n });\n return this.parseResponse<T>(response);\n }\n\n private buildUrl(path: string, query?: QueryParams): string {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n return url.toString();\n }\n\n private authHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n private async fetchWithTimeout(\n url: string,\n init: RequestInit,\n ): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n this.timeoutMs,\n );\n\n try {\n return await fetch(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n\n private parseRateLimit(response: Response): RateLimitHeaders | undefined {\n const limit = response.headers.get(\"X-RateLimit-Limit\");\n const remaining = response.headers.get(\"X-RateLimit-Remaining\");\n const reset = response.headers.get(\"X-RateLimit-Reset\");\n\n if (limit === null || remaining === null || reset === null) {\n return undefined;\n }\n\n return {\n limit: Number(limit),\n remaining: Number(remaining),\n reset: Number(reset),\n };\n }\n\n private async parseResponse<T>(response: Response): Promise<ApiResponse<T>> {\n const requestId =\n response.headers.get(\"X-Request-Id\") ?? undefined;\n const rateLimit = this.parseRateLimit(response);\n\n if (!response.ok) {\n let body: ApiErrorBody;\n try {\n body = (await response.json()) as ApiErrorBody;\n } catch {\n body = {\n error: \"Unknown error\",\n detail: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n const retryAfter = response.headers.get(\"Retry-After\");\n throw createApiError(response.status, body, retryAfter);\n }\n\n const data = (await response.json()) as T;\n return { data, requestId, rateLimit };\n }\n}\n","import type { HttpClient } from \"../http/client.js\";\n\nexport abstract class BaseModule {\n protected readonly http: HttpClient;\n\n constructor(http: HttpClient) {\n this.http = http;\n }\n}\n","import { TimeoutError } from \"../errors/index.js\";\n\nconst DEFAULT_INTERVAL_MS = 2_000;\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\nexport async function poll<T>(\n jobId: string,\n fn: () => Promise<T>,\n isDone: (result: T) => boolean,\n options?: { intervalMs?: number; timeoutMs?: number },\n): Promise<T> {\n const intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;\n const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n const result = await fn();\n if (isDone(result)) {\n return result;\n }\n\n if (Date.now() >= deadline) {\n throw new TimeoutError(jobId, timeoutMs);\n }\n\n await sleep(intervalMs);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { BaseModule } from \"./base.js\";\nimport { poll } from \"../utils/poll.js\";\nimport type {\n ListTranscriptionsParams,\n TranscribeFileParams,\n TranscribeUrlParams,\n TranscriptionJob,\n} from \"../types/asr.js\";\nimport type { PaginatedResponse, PollOptions } from \"../types/common.js\";\nimport type { QueryParams } from \"../http/types.js\";\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"failed\"]);\n\nexport class ASRModule extends BaseModule {\n async transcribe(params: TranscribeUrlParams): Promise<TranscriptionJob> {\n const body: Record<string, unknown> = { audio: params.audio };\n if (params.language !== undefined) body[\"language\"] = params.language;\n if (params.webhookUrl !== undefined) body[\"webhookUrl\"] = params.webhookUrl;\n\n const { data } = await this.http.post<TranscriptionJob>(\n \"/dev/v1/transcribe\",\n body,\n );\n return data;\n }\n\n async transcribeFile(\n filePath: string,\n params?: TranscribeFileParams,\n ): Promise<TranscriptionJob> {\n const fields: Record<string, string | undefined> = {\n language: params?.language,\n webhook_url: params?.webhookUrl,\n };\n\n const { data } = await this.http.postMultipart<TranscriptionJob>(\n \"/dev/v1/transcribe\",\n filePath,\n fields,\n );\n return data;\n }\n\n async getResult(jobId: string): Promise<TranscriptionJob> {\n const { data } = await this.http.get<TranscriptionJob>(\n `/dev/v1/transcribe/${jobId}`,\n );\n return data;\n }\n\n async list(\n params?: ListTranscriptionsParams,\n ): Promise<PaginatedResponse<TranscriptionJob>> {\n const query: QueryParams = {};\n if (params?.limit !== undefined) query[\"limit\"] = params.limit;\n if (params?.cursor !== undefined) query[\"cursor\"] = params.cursor;\n if (params?.status !== undefined) query[\"status\"] = params.status;\n\n const { data } = await this.http.get<PaginatedResponse<TranscriptionJob>>(\n \"/dev/v1/transcriptions\",\n query,\n );\n return data;\n }\n\n async poll(\n jobId: string,\n options?: PollOptions,\n ): Promise<TranscriptionJob> {\n return poll(\n jobId,\n () => this.getResult(jobId),\n (result) => TERMINAL_STATUSES.has(result.status),\n options,\n );\n }\n}\n","import { BaseModule } from \"./base.js\";\nimport type {\n ListVoicesParams,\n TtsGenerateParams,\n TtsGenerateResponse,\n VoiceListResponse,\n} from \"../types/tts.js\";\nimport type { QueryParams } from \"../http/types.js\";\n\nexport class TTSModule extends BaseModule {\n async listVoices(params?: ListVoicesParams): Promise<VoiceListResponse> {\n const query: QueryParams = {};\n if (params?.language !== undefined) {\n query[\"language\"] = params.language;\n }\n const { data } = await this.http.get<VoiceListResponse>(\n \"/dev/v1/tts/voices\",\n query,\n );\n return data;\n }\n\n async generate(params: TtsGenerateParams): Promise<TtsGenerateResponse> {\n const body: Record<string, unknown> = {\n text: params.text,\n voice_id: params.voice_id,\n language: params.language,\n };\n if (params.speed !== undefined) body[\"speed\"] = params.speed;\n if (params.output_format !== undefined) {\n body[\"output_format\"] = params.output_format;\n }\n\n const { data } = await this.http.post<TtsGenerateResponse>(\n \"/dev/v1/tts/generate\",\n body,\n );\n return data;\n }\n}\n","import { BaseModule } from \"./base.js\";\nimport { poll } from \"../utils/poll.js\";\nimport type {\n AnimateGenerateParams,\n AnimateJobResponse,\n AnimateResultResponse,\n} from \"../types/animate.js\";\nimport type { PollOptions } from \"../types/common.js\";\n\nconst TERMINAL_STATUSES = new Set([\"completed\", \"failed\"]);\n\nexport class AnimateModule extends BaseModule {\n async generate(params: AnimateGenerateParams): Promise<AnimateJobResponse> {\n const body: Record<string, unknown> = {\n image_url: params.image_url,\n audio_url: params.audio_url,\n };\n if (params.output_format !== undefined) {\n body[\"output_format\"] = params.output_format;\n }\n\n const { data } = await this.http.post<AnimateJobResponse>(\n \"/dev/v1/animate/generate\",\n body,\n );\n return data;\n }\n\n async getResult(jobId: string): Promise<AnimateResultResponse> {\n const { data } = await this.http.get<AnimateResultResponse>(\n `/dev/v1/animate/${jobId}`,\n );\n return data;\n }\n\n async poll(\n jobId: string,\n options?: PollOptions,\n ): Promise<AnimateResultResponse> {\n return poll(\n jobId,\n () => this.getResult(jobId),\n (result) => TERMINAL_STATUSES.has(result.status),\n options,\n );\n }\n}\n","import { BaseModule } from \"./base.js\";\nimport type { ExplainParams, ExplainResponse } from \"../types/explain.js\";\n\nexport class ExplainModule extends BaseModule {\n async process(params: ExplainParams): Promise<ExplainResponse> {\n const body: Record<string, unknown> = {\n text: params.text,\n language: params.language,\n action: params.action,\n };\n if (params.target_language !== undefined) {\n body[\"target_language\"] = params.target_language;\n }\n if (params.max_tokens !== undefined) {\n body[\"max_tokens\"] = params.max_tokens;\n }\n\n const { data } = await this.http.post<ExplainResponse>(\n \"/dev/v1/explain\",\n body,\n );\n return data;\n }\n}\n","import { BaseModule } from \"./base.js\";\nimport type {\n UsageBalanceResponse,\n UsageBreakdownParams,\n UsageBreakdownResponse,\n} from \"../types/usage.js\";\nimport type { QueryParams } from \"../http/types.js\";\n\nexport class UsageModule extends BaseModule {\n async getBalance(): Promise<UsageBalanceResponse> {\n const { data } = await this.http.get<UsageBalanceResponse>(\"/dev/v1/usage\");\n return data;\n }\n\n async getBreakdown(\n params: UsageBreakdownParams,\n ): Promise<UsageBreakdownResponse> {\n const query: QueryParams = {\n start_date: params.start_date,\n end_date: params.end_date,\n };\n if (params.module !== undefined) query[\"module\"] = params.module;\n\n const { data } = await this.http.get<UsageBreakdownResponse>(\n \"/dev/v1/usage/breakdown\",\n query,\n );\n return data;\n }\n}\n","import { HttpClient } from \"./http/client.js\";\nimport { ASRModule } from \"./modules/asr.js\";\nimport { TTSModule } from \"./modules/tts.js\";\nimport { AnimateModule } from \"./modules/animate.js\";\nimport { ExplainModule } from \"./modules/explain.js\";\nimport { UsageModule } from \"./modules/usage.js\";\n\nexport interface VoiceMakerConfig {\n apiKey: string;\n baseUrl?: string;\n timeoutMs?: number;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.myvoicemaker.ai\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\nexport class VoiceMaker {\n readonly tts: TTSModule;\n readonly asr: ASRModule;\n readonly animate: AnimateModule;\n readonly explain: ExplainModule;\n readonly usage: UsageModule;\n\n constructor(config: VoiceMakerConfig) {\n if (!config.apiKey) {\n throw new Error(\"VoiceMaker: apiKey is required\");\n }\n\n const http = new HttpClient({\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n });\n\n this.tts = new TTSModule(http);\n this.asr = new ASRModule(http);\n this.animate = new AnimateModule(http);\n this.explain = new ExplainModule(http);\n this.usage = new UsageModule(http);\n }\n}\n"]}