@breeze.blue/sdk 0.20.0 → 0.21.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.21.0
4
+
5
+ - Support request-scoped speaker boost across HTTP and realtime TTS, with performance instructions taking priority when guidance exceeds 1.
6
+ - Serialize documented request controls only.
7
+ - Honor the clone reference-denoising switch (disabled by default).
8
+ - Read the account's plan, billing period, monthly credits, saved voice and project limits and generation concurrency with `client.account.entitlements()`, typed as `Entitlements`.
9
+ - Breaking: remove `voices.getSettings(...)`, `voices.editSettings(...)`, the `VoiceSettings` type and `Voice.settings`; the voice settings endpoints are removed.
10
+ - TTS guidance no longer inherits saved voice settings; omitted `voiceSettings.guidanceScale` uses the default 1.
11
+ - Breaking: remove `voices.favorite(...)` and `voices.unfavorite(...)`; the favorite endpoints are removed. `isFavorited` and the `favoritesOnly` filter remain.
12
+
13
+ ## 0.20.1
14
+
15
+ - Studio list methods type their filters: `StudioProjectListParams`, `StudioChapterListParams`, `StudioClipListParams` and `StudioFileListParams`.
16
+ - `studio.files.upload` accepts `waitTimeout`.
17
+ - Studio file upload and processing failures reject with `BreezeBlueStudioFileError`, which carries the latest file record in `file`.
18
+ - Studio response types mark fields the API always returns as required.
19
+ - The default `fetch` is called unbound, so the client works in browsers without passing `fetch`; a custom `window.fetch` no longer throws "Illegal invocation".
20
+ - Studio methods without query parameters take request options as the last argument, e.g. `studio.projects.get(id, { timeout })`. The `(…, params, options)` form still works and is deprecated.
21
+ - Studio file responses type `status` as `StudioFileStatus`, and `uploadUrl` returns `expiresIn`.
22
+
3
23
  ## 0.20.0
4
24
 
5
25
  - Manage Studio projects, chapters, clips, auxiliary tracks, audio instances and files through `client.studio`.
package/README.md CHANGED
@@ -7,6 +7,8 @@ models, and account usage.
7
7
  The root entrypoint is safe to import in Node, browser, and edge runtimes. Local
8
8
  audio playback helpers live in the Node-only `@breeze.blue/sdk/node` subpath.
9
9
 
10
+ Guidance accepts 1–10; when omitted, the default 1 is used. HTTP speed and volume are per request and default to 1. Use `voiceSettings: { useSpeakerBoost: true }` for closer similarity to the reference voice (default false): it is ignored with non-empty instructions and guidance above 1, and otherwise instructions are not used. Realtime fixes boost at session creation; create a new session to change instructions while boost applies. Pass `removeBackgroundNoise: true` to denoise a clone sample (default false).
11
+
10
12
  ## Install
11
13
 
12
14
  ```sh
@@ -421,7 +423,6 @@ const taggedFavorites = await client.voices.search({
421
423
  const firstVoiceId = voices.voices[0].voiceId;
422
424
 
423
425
  const voice = await client.voices.get(firstVoiceId);
424
- const settings = await client.voices.getSettings(firstVoiceId);
425
426
 
426
427
  const randomVoice = await client.voices.random();
427
428
  console.log(randomVoice.voiceId, randomVoice.name);
@@ -563,7 +564,7 @@ const saved = await client.voices.savePreview({
563
564
  });
564
565
  ```
565
566
 
566
- Edit, tune settings, or delete a saved voice:
567
+ Edit or delete a saved voice:
567
568
 
568
569
  ```ts
569
570
  await client.voices.edit(saved.voiceId, {
@@ -573,11 +574,8 @@ await client.voices.edit(saved.voiceId, {
573
574
  });
574
575
  // null clears nullable metadata; [] clears tone. Omitted fields remain unchanged.
575
576
  await client.voices.edit(saved.voiceId, { accent: null, tone: [] });
576
- await client.voices.editSettings(saved.voiceId, { guidanceScale: 1.2 });
577
- await client.voices.favorite(firstVoiceId);
578
577
  await client.voices.updateTags(firstVoiceId, ["narration", "novel=三体"]);
579
578
  await client.voices.updateTags(firstVoiceId, []); // Resume owner tag inheritance.
580
- await client.voices.unfavorite(firstVoiceId);
581
579
  await client.voices.delete(saved.voiceId);
582
580
  ```
583
581
 
@@ -592,6 +590,8 @@ language-to-accent cascade at runtime.
592
590
  ```ts
593
591
  const models = await client.models.list();
594
592
  const balance = await client.account.balance();
593
+ const entitlements = await client.account.entitlements();
594
+ console.log(entitlements.planCode, entitlements.maxConcurrentGenerations);
595
595
  const currentKey = (await client.account.currentApiKey()).apiKey;
596
596
  console.log(currentKey.status, currentKey.creditRemaining);
597
597
  const usage = await client.account.usage({ days: 7 });
@@ -640,9 +640,9 @@ Clone previews automatically generate a short script in the detected reference a
640
640
 
641
641
  ### HTTP TTS speed
642
642
 
643
- Pass `voiceSettings: { speed: 1.25 }` to control speech speed without changing pitch, from 0.5 to 2.0. Omission always means 1.0; saved voice speed is not inherited. Sync, async and HTTP streaming support this parameter; Realtime does not.
643
+ Pass `voiceSettings: { speed: 1.25 }` to control speech speed without changing pitch, from 0.5 to 2.0. Omission always means 1.0. Sync, async and HTTP streaming support this parameter; Realtime does not.
644
644
 
645
- Pass `voiceSettings: { volume: 1.5 }` to apply a request-level linear amplitude multiplier. Values range from 0.01 to 2.0; omission means 1.0. Values above 1.0 may clip peaks. Sync, async and HTTP streaming support this parameter; it does not change saved voice settings or apply to Realtime.
645
+ Pass `voiceSettings: { volume: 1.5 }` to apply a request-level linear amplitude multiplier. Values range from 0.01 to 2.0; omission means 1.0. Values above 1.0 may clip peaks. Sync, async and HTTP streaming support this parameter; Realtime does not.
646
646
 
647
647
  ## Word timing
648
648
 
@@ -659,3 +659,5 @@ Clone preview creation accepts an omitted name. The server uses the filename ste
659
659
  `client.studio` exposes `projects`, `chapters`, `clips`, `tracks`, `instances`, and `files`. Import scripts with existing voice IDs, edit inherited instructions and silence, upload MP3/WAV materials, and arrange background audio. Project writes require the latest edit token and a UUID operation ID. Conflicts preserve error metadata and are not retried automatically.
660
660
 
661
661
  See the [Studio initialization guide](https://docs.breezeblue.ai/guides/studio-projects) for a complete workflow. Signed uploads use a separate request without the API key. Management operations do not generate speech or export projects.
662
+
663
+ `client.studio.files.upload(blob, { operationId, name, projectId })` creates the file record, uploads to the signed URL, completes the upload and waits for `ready`; failures reject with `BreezeBlueStudioFileError`. Timeline positions, trims and lengths are 48 kHz frames; use `secondsToFrames` and `framesToSeconds` to convert.
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { StudioResource } from "./studio.js";
2
2
  import { SpeechTimingStream, type SpeechWithTimestamps } from "./timestamps.js";
3
3
  import { AudioResponse } from "./audio.js";
4
- import type { AudioRequestOptions, BreezeBlueWebSocket, AsyncTextToSpeechJob, Balance, BreezeBlueClientOptions, CurrentApiKeyResponse, GenericStatus, GenerationJob, HistoryItem, HistoryList, HistoryListParams, Model, RequestOptions, RealtimeTextToSpeechConnectOptions, RealtimeTextToSpeechEvent, RealtimeTextToSpeechManagedConnectOptions, RealtimeTextToSpeechMessage, RealtimeTextToSpeechSession, RealtimeTextToSpeechSessionRequest, SavedVoice, SaveVoiceRequest, StreamTextToSpeechOptions, TextToSpeechRequest, TtsEnhanceRequest, TtsEnhanceResponse, Usage, UsageParams, Voice, VoiceClonePreview, VoiceClonePreviewRequest, VoiceDesignRequest, VoiceDesignResponse, VoiceDesignStreamRequest, VoiceEditRequest, VoiceList, VoiceLocalizeJob, VoiceLocalizePreviewRequest, VoiceLocalizePreviewStatus, VoiceRemixPreviewRequest, VoiceRemixPrepareRequest, VoiceRemixPresets, VoiceRemixPreparation, VoiceRemixJob, VoiceRemixPreviewStatus, VoiceMetadataOptions, VoiceRandomParams, VoiceSearchParams, VoiceSettings } from "./types.js";
4
+ import type { AudioRequestOptions, BreezeBlueWebSocket, AsyncTextToSpeechJob, Balance, BreezeBlueClientOptions, CurrentApiKeyResponse, Entitlements, GenericStatus, GenerationJob, HistoryItem, HistoryList, HistoryListParams, Model, RequestOptions, RealtimeTextToSpeechConnectOptions, RealtimeTextToSpeechEvent, RealtimeTextToSpeechManagedConnectOptions, RealtimeTextToSpeechMessage, RealtimeTextToSpeechSession, RealtimeTextToSpeechSessionRequest, SavedVoice, SaveVoiceRequest, StreamTextToSpeechOptions, TextToSpeechRequest, TtsEnhanceRequest, TtsEnhanceResponse, Usage, UsageParams, Voice, VoiceClonePreview, VoiceClonePreviewRequest, VoiceDesignRequest, VoiceDesignResponse, VoiceDesignStreamRequest, VoiceEditRequest, VoiceList, VoiceLocalizeJob, VoiceLocalizePreviewRequest, VoiceLocalizePreviewStatus, VoiceRemixPreviewRequest, VoiceRemixPrepareRequest, VoiceRemixPresets, VoiceRemixPreparation, VoiceRemixJob, VoiceRemixPreviewStatus, VoiceMetadataOptions, VoiceRandomParams, VoiceSearchParams } from "./types.js";
5
5
  export declare class BreezeBlueClient {
6
6
  readonly apiKey: string | undefined;
7
7
  readonly baseUrl: string;
@@ -232,11 +232,7 @@ declare class VoicesResource {
232
232
  metadataOptions(options?: RequestOptions): Promise<VoiceMetadataOptions>;
233
233
  edit(voiceId: string, request: VoiceEditRequest, options?: RequestOptions): Promise<GenericStatus>;
234
234
  updateTags(voiceId: string, tags: string[], options?: RequestOptions): Promise<Voice>;
235
- favorite(voiceId: string, options?: RequestOptions): Promise<Voice>;
236
- unfavorite(voiceId: string, options?: RequestOptions): Promise<Voice>;
237
235
  delete(voiceId: string, options?: RequestOptions): Promise<GenericStatus>;
238
- getSettings(voiceId: string, options?: RequestOptions): Promise<Required<VoiceSettings>>;
239
- editSettings(voiceId: string, settings: VoiceSettings, options?: RequestOptions): Promise<Required<VoiceSettings>>;
240
236
  /**
241
237
  * Generate a clone preview from a single audio sample. Returns a
242
238
  * `generatedVoiceId`; call {@link savePreview} after the user accepts
@@ -298,6 +294,8 @@ declare class AccountResource {
298
294
  private readonly client;
299
295
  constructor(client: BreezeBlueClient);
300
296
  balance(options?: RequestOptions): Promise<Balance>;
297
+ /** Return the account's plan, billing period and generation limits. */
298
+ entitlements(options?: RequestOptions): Promise<Entitlements>;
301
299
  /** Return the authenticating API key and its current Key Budget counters. */
302
300
  currentApiKey(options?: RequestOptions): Promise<CurrentApiKeyResponse>;
303
301
  usage(params?: UsageParams, options?: RequestOptions): Promise<Usage>;
package/dist/client.js CHANGED
@@ -42,7 +42,9 @@ export class BreezeBlueClient {
42
42
  // clientSecret works without one, so missing keys are reported lazily.
43
43
  this.apiKey = options.apiKey ?? envApiKey;
44
44
  this.baseUrl = normalizeBaseUrl(options.baseUrl ?? envBaseUrl ?? DEFAULT_BASE_URL);
45
- this.fetch = options.fetch ?? globalThis.fetch;
45
+ const fetchImpl = options.fetch;
46
+ // Call fetch unbound: browsers reject window.fetch invoked with the client as `this`.
47
+ this.fetch = (input, init) => (fetchImpl ?? globalThis.fetch)(input, init);
46
48
  this.webSocket = options.webSocket ?? readGlobalWebSocket();
47
49
  this.headers = options.headers;
48
50
  this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
@@ -103,6 +105,18 @@ export class BreezeBlueClient {
103
105
  return headers;
104
106
  }
105
107
  }
108
+ function ttsRequest(request) {
109
+ const { text, modelId, languageCode, instructions, voiceSettings } = request;
110
+ return {
111
+ text, modelId, languageCode, instructions,
112
+ voiceSettings: voiceSettings == null ? voiceSettings : {
113
+ guidanceScale: voiceSettings.guidanceScale,
114
+ useSpeakerBoost: voiceSettings.useSpeakerBoost,
115
+ speed: voiceSettings.speed,
116
+ volume: voiceSettings.volume,
117
+ },
118
+ };
119
+ }
106
120
  class TextToSpeechResource {
107
121
  client;
108
122
  realtime;
@@ -111,26 +125,25 @@ class TextToSpeechResource {
111
125
  this.realtime = new RealtimeTextToSpeechResource(client);
112
126
  }
113
127
  convert(voiceId, request, options = {}) {
114
- return this.client.requestAudio("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}`, { outputFormat: options.outputFormat }, request, options);
128
+ return this.client.requestAudio("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}`, { outputFormat: options.outputFormat }, ttsRequest(request), options);
115
129
  }
116
130
  createJob(voiceId, request, options = {}) {
117
- return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}`, { outputFormat: options.outputFormat, delivery: "async" }, request, options);
131
+ return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}`, { outputFormat: options.outputFormat, delivery: "async" }, ttsRequest(request), options);
118
132
  }
119
133
  createJobWithTimestamps(voiceId, request, options = {}) {
120
- return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/with-timestamps`, { outputFormat: options.outputFormat, delivery: "async" }, request, options);
134
+ return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/with-timestamps`, { outputFormat: options.outputFormat, delivery: "async" }, ttsRequest(request), options);
121
135
  }
122
136
  stream(voiceId, request, options = {}) {
123
137
  return this.client.requestAudio("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/stream`, {
124
138
  outputFormat: options.outputFormat,
125
- optimizeStreamingLatency: options.optimizeStreamingLatency,
126
139
  enableLogging: options.enableLogging,
127
- }, request, options);
140
+ }, ttsRequest(request), options);
128
141
  }
129
142
  convertWithTimestamps(voiceId, request, options = {}) {
130
- return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/with-timestamps`, { outputFormat: options.outputFormat }, request, options);
143
+ return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/with-timestamps`, { outputFormat: options.outputFormat }, ttsRequest(request), options);
131
144
  }
132
145
  async streamWithTimestamps(voiceId, request, options = {}) {
133
- const response = await this.client.request("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/stream/with-timestamps`, { outputFormat: options.outputFormat, optimizeStreamingLatency: options.optimizeStreamingLatency, enableLogging: options.enableLogging }, request, options);
146
+ const response = await this.client.request("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/stream/with-timestamps`, { outputFormat: options.outputFormat, enableLogging: options.enableLogging }, { ...ttsRequest(request), timestampMode: request.timestampMode }, options);
134
147
  return new SpeechTimingStream(response);
135
148
  }
136
149
  enhance(request, options) {
@@ -143,7 +156,14 @@ class RealtimeTextToSpeechResource {
143
156
  this.client = client;
144
157
  }
145
158
  createSession(voiceId, request = {}, options) {
146
- return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/realtime-sessions`, undefined, request, options);
159
+ return this.client.requestJson("POST", `/v1/text-to-speech/${encodeURIComponent(voiceId)}/realtime-sessions`, undefined, {
160
+ modelId: request.modelId,
161
+ languageCode: request.languageCode,
162
+ instructions: request.instructions,
163
+ voiceSettings: request.voiceSettings == null ? request.voiceSettings : { guidanceScale: request.voiceSettings.guidanceScale, useSpeakerBoost: request.voiceSettings.useSpeakerBoost },
164
+ inactivityTimeoutSeconds: request.inactivityTimeoutSeconds,
165
+ enableLogging: request.enableLogging,
166
+ }, options);
147
167
  }
148
168
  async connect(voiceId, options = {}) {
149
169
  if ((options.clientSecret !== undefined ||
@@ -1541,24 +1561,9 @@ class VoicesResource {
1541
1561
  const result = await this.client.requestJson("PUT", `/v1/voices/${encodeURIComponent(voiceId)}/tags`, undefined, { tags }, options);
1542
1562
  return stripHiddenVoiceFields(result);
1543
1563
  }
1544
- async favorite(voiceId, options) {
1545
- const result = await this.client.requestJson("PUT", `/v1/voices/${encodeURIComponent(voiceId)}/favorite`, undefined, undefined, options);
1546
- return stripHiddenVoiceFields(result);
1547
- }
1548
- async unfavorite(voiceId, options) {
1549
- const result = await this.client.requestJson("DELETE", `/v1/voices/${encodeURIComponent(voiceId)}/favorite`, undefined, undefined, options);
1550
- return stripHiddenVoiceFields(result);
1551
- }
1552
1564
  delete(voiceId, options) {
1553
1565
  return this.client.requestJson("DELETE", `/v1/voices/${encodeURIComponent(voiceId)}`, undefined, undefined, options);
1554
1566
  }
1555
- // -- voice settings ---------------------------------------------------
1556
- getSettings(voiceId, options) {
1557
- return this.client.requestJson("GET", `/v1/voices/${encodeURIComponent(voiceId)}/settings`, undefined, undefined, options);
1558
- }
1559
- editSettings(voiceId, settings, options) {
1560
- return this.client.requestJson("PATCH", `/v1/voices/${encodeURIComponent(voiceId)}/settings`, undefined, settings, options);
1561
- }
1562
1567
  // -- two-step preview → save flow -------------------------------------
1563
1568
  /**
1564
1569
  * Generate a clone preview from a single audio sample. Returns a
@@ -1574,14 +1579,16 @@ class VoicesResource {
1574
1579
  * {@link savePreview}.
1575
1580
  */
1576
1581
  createDesignPreview(request, options = {}) {
1577
- return this.client.requestJson("POST", "/v1/voice-previews/design", { outputFormat: options.outputFormat }, request, options);
1582
+ const { voiceDescription, text, modelId, languageCode, guidanceScale, previewCount } = request;
1583
+ return this.client.requestJson("POST", "/v1/voice-previews/design", { outputFormat: options.outputFormat }, { voiceDescription, text, modelId, languageCode, guidanceScale, previewCount }, options);
1578
1584
  }
1579
1585
  /**
1580
1586
  * Generate exactly one voice design preview as live 24 kHz mono PCM.
1581
1587
  * A clean end means `generatedVoiceId` is ready for {@link savePreview}.
1582
1588
  */
1583
1589
  streamDesignPreview(request, options) {
1584
- return this.client.requestAudio("POST", "/v1/voice-previews/design/stream", undefined, request, options);
1590
+ return this.client.requestAudio("POST", "/v1/voice-previews/design/stream", undefined, { voiceDescription: request.voiceDescription, text: request.text, modelId: request.modelId,
1591
+ languageCode: request.languageCode, guidanceScale: request.guidanceScale }, options);
1585
1592
  }
1586
1593
  /** List curated voice changes and their sample recordings. */
1587
1594
  listRemixPresets(options) {
@@ -1629,7 +1636,6 @@ class VoicesResource {
1629
1636
  tags: request.tags,
1630
1637
  primaryCategoryCode: request.primaryCategoryCode,
1631
1638
  visibility: request.visibility,
1632
- playedNotSelectedVoiceIds: request.playedNotSelectedVoiceIds,
1633
1639
  languageCode: request.languageCode,
1634
1640
  gender: request.gender,
1635
1641
  age: request.age,
@@ -1674,6 +1680,10 @@ class AccountResource {
1674
1680
  balance(options) {
1675
1681
  return this.client.requestJson("GET", "/v1/balance", undefined, undefined, options);
1676
1682
  }
1683
+ /** Return the account's plan, billing period and generation limits. */
1684
+ entitlements(options) {
1685
+ return this.client.requestJson("GET", "/v1/entitlements", undefined, undefined, options);
1686
+ }
1677
1687
  /** Return the authenticating API key and its current Key Budget counters. */
1678
1688
  currentApiKey(options) {
1679
1689
  return this.client.requestJson("GET", "/v1/api-keys/current", undefined, undefined, options);
@@ -1776,17 +1786,10 @@ function clonePreviewForm(request) {
1776
1786
  if (request.name != null && typeof request.name !== "string") {
1777
1787
  throw new BreezeBlueConfigurationError("Clone name must be a string or null.");
1778
1788
  }
1779
- if (request.removeBackgroundNoise) {
1780
- throw new BreezeBlueConfigurationError("removeBackgroundNoise is not supported by the Breeze Developer API.");
1781
- }
1782
- for (const field of ["text", "instructions", "languageCode", "previewLanguageCode"]) {
1783
- if (field in request) {
1784
- throw new BreezeBlueConfigurationError(`Clone previews do not accept ${field}; the script and language are generated automatically.`);
1785
- }
1786
- }
1787
1789
  const form = new FormData();
1788
1790
  appendOptional(form, "name", request.name ?? undefined);
1789
1791
  appendOptional(form, "description", request.description);
1792
+ appendOptional(form, "remove_background_noise", request.removeBackgroundNoise ?? false);
1790
1793
  for (const file of normalizeFiles(request.file, request.files, { required: true })) {
1791
1794
  appendFile(form, "files", file);
1792
1795
  }
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { StudioFileView } from "./studio-types.js";
1
2
  export interface BreezeBlueErrorPayload {
2
3
  ok?: false;
3
4
  code?: string;
@@ -37,6 +38,15 @@ export declare class BreezeBlueRealtimeError extends BreezeBlueError {
37
38
  cause?: unknown;
38
39
  });
39
40
  }
41
+ /**
42
+ * A Studio file upload or processing step failed. `file` holds the latest
43
+ * file record; inspect `status`, `errorCode` and `errorMessage`, then retry
44
+ * processing or upload again.
45
+ */
46
+ export declare class BreezeBlueStudioFileError extends BreezeBlueError {
47
+ readonly file: StudioFileView;
48
+ constructor(message: string, file: StudioFileView);
49
+ }
40
50
  export declare class BreezeBlueAPIError extends BreezeBlueError {
41
51
  readonly status: number;
42
52
  readonly code: string;
package/dist/errors.js CHANGED
@@ -33,6 +33,18 @@ export class BreezeBlueRealtimeError extends BreezeBlueError {
33
33
  this.recoverable = params.recoverable ?? false;
34
34
  }
35
35
  }
36
+ /**
37
+ * A Studio file upload or processing step failed. `file` holds the latest
38
+ * file record; inspect `status`, `errorCode` and `errorMessage`, then retry
39
+ * processing or upload again.
40
+ */
41
+ export class BreezeBlueStudioFileError extends BreezeBlueError {
42
+ file;
43
+ constructor(message, file) {
44
+ super(message);
45
+ this.file = file;
46
+ }
47
+ }
36
48
  export class BreezeBlueAPIError extends BreezeBlueError {
37
49
  status;
38
50
  code;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { AudioResponse } from "./audio.js";
2
- export { BreezeBlueAPIError, BreezeBlueAuthenticationError, BreezeBlueBadRequestError, BreezeBlueConfigurationError, BreezeBlueConflictError, BreezeBlueError, BreezeBlueForbiddenError, BreezeBlueGenerationNotReadyError, BreezeBlueInsufficientCreditsError, BreezeBlueNotFoundError, BreezeBlueRateLimitError, BreezeBlueRealtimeError, BreezeBlueServiceUnavailableError, BreezeBlueUpstreamError, BreezeBlueValidationError, } from "./errors.js";
2
+ export { BreezeBlueAPIError, BreezeBlueAuthenticationError, BreezeBlueBadRequestError, BreezeBlueConfigurationError, BreezeBlueConflictError, BreezeBlueError, BreezeBlueForbiddenError, BreezeBlueGenerationNotReadyError, BreezeBlueInsufficientCreditsError, BreezeBlueNotFoundError, BreezeBlueRateLimitError, BreezeBlueRealtimeError, BreezeBlueServiceUnavailableError, BreezeBlueStudioFileError, BreezeBlueUpstreamError, BreezeBlueValidationError, } from "./errors.js";
3
3
  export { BreezeBlueClient, ManagedRealtimeTextToSpeechConnection, RealtimeTextToSpeechConnection, } from "./client.js";
4
4
  export { SDK_NAME, SDK_VERSION } from "./version.js";
5
5
  export type * from "./types.js";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { AudioResponse } from "./audio.js";
2
- export { BreezeBlueAPIError, BreezeBlueAuthenticationError, BreezeBlueBadRequestError, BreezeBlueConfigurationError, BreezeBlueConflictError, BreezeBlueError, BreezeBlueForbiddenError, BreezeBlueGenerationNotReadyError, BreezeBlueInsufficientCreditsError, BreezeBlueNotFoundError, BreezeBlueRateLimitError, BreezeBlueRealtimeError, BreezeBlueServiceUnavailableError, BreezeBlueUpstreamError, BreezeBlueValidationError, } from "./errors.js";
2
+ export { BreezeBlueAPIError, BreezeBlueAuthenticationError, BreezeBlueBadRequestError, BreezeBlueConfigurationError, BreezeBlueConflictError, BreezeBlueError, BreezeBlueForbiddenError, BreezeBlueGenerationNotReadyError, BreezeBlueInsufficientCreditsError, BreezeBlueNotFoundError, BreezeBlueRateLimitError, BreezeBlueRealtimeError, BreezeBlueServiceUnavailableError, BreezeBlueStudioFileError, BreezeBlueUpstreamError, BreezeBlueValidationError, } from "./errors.js";
3
3
  export { BreezeBlueClient, ManagedRealtimeTextToSpeechConnection, RealtimeTextToSpeechConnection, } from "./client.js";
4
4
  export { SDK_NAME, SDK_VERSION } from "./version.js";
5
5
  export * from "./voice-metadata.js";
@@ -117,15 +117,15 @@ export interface StudioClipView {
117
117
  instructions: string;
118
118
  voiceId: string | null;
119
119
  voice: StudioVoiceSummary | null;
120
- playback: StudioPlayback;
120
+ playback: StudioPlaybackView;
121
121
  trailingSilenceMs: number | null;
122
122
  effectiveInstructions: string;
123
123
  effectiveTrailingSilenceMs: number;
124
124
  version: number;
125
125
  }
126
126
  export interface StudioDeleted {
127
- deleted?: boolean;
128
- editToken?: string | null;
127
+ deleted: boolean;
128
+ editToken: string | null;
129
129
  }
130
130
  export interface StudioEdit {
131
131
  expectedEditToken: string;
@@ -160,7 +160,7 @@ export interface StudioFileView {
160
160
  projectId: string | null;
161
161
  name: string;
162
162
  revision: number;
163
- status: string;
163
+ status: StudioFileStatus;
164
164
  frames: number | null;
165
165
  sampleRate: number;
166
166
  sizeBytes: number | null;
@@ -210,11 +210,16 @@ export interface StudioInstanceView {
210
210
  trimStart: number;
211
211
  trimEnd: number;
212
212
  effects: StudioEffects;
213
- length?: number | null;
214
- phase?: number;
215
- envelopeOffset?: number;
216
- envelopeLength?: number | null;
217
- issues?: Array<string>;
213
+ length: number | null;
214
+ phase: number;
215
+ envelopeOffset: number;
216
+ envelopeLength: number | null;
217
+ issues: Array<string>;
218
+ }
219
+ export type StudioFileStatus = "uploading" | "queued" | "running" | "ready" | "failed";
220
+ export interface StudioPlaybackView {
221
+ speed: number;
222
+ volume: number;
218
223
  }
219
224
  export interface StudioPlayback {
220
225
  speed?: number;
@@ -265,16 +270,16 @@ export interface StudioProjectPatch {
265
270
  export interface StudioProjectResult {
266
271
  project: StudioProjectView;
267
272
  editToken: string;
268
- clientRefs?: Record<string, string>;
269
- createdIds?: Array<string>;
273
+ clientRefs: Record<string, string>;
274
+ createdIds: Array<string>;
270
275
  }
271
276
  export interface StudioProjectView {
272
- title?: string;
273
- description?: string;
274
- ttsSettings?: StudioTtsSettings | null;
275
- defaultVoiceId?: string | null;
276
- defaultInstructions?: string;
277
- defaultSilenceMs?: number;
277
+ title: string;
278
+ description: string;
279
+ ttsSettings: StudioTtsSettings | null;
280
+ defaultVoiceId: string | null;
281
+ defaultInstructions: string;
282
+ defaultSilenceMs: number;
278
283
  id: string;
279
284
  editToken: string;
280
285
  createdAt: string;
@@ -314,11 +319,11 @@ export interface StudioTrackResult {
314
319
  export interface StudioTrackView {
315
320
  id: string;
316
321
  name: string;
317
- chapterId?: string | null;
318
- volume?: number;
319
- muted?: boolean;
320
- readonly?: boolean;
321
- instances?: Array<StudioInstanceView>;
322
+ chapterId: string | null;
323
+ volume: number;
324
+ muted: boolean;
325
+ readonly: boolean;
326
+ instances: Array<StudioInstanceView>;
322
327
  }
323
328
  export interface StudioTtsSettings {
324
329
  model?: string | null;
@@ -328,10 +333,39 @@ export interface StudioTtsSettings {
328
333
  }
329
334
  export interface StudioUploadResult {
330
335
  uploadUrl: string;
331
- headers?: Record<string, string>;
336
+ headers: Record<string, string>;
337
+ expiresIn: number;
332
338
  }
333
339
  export interface StudioVoiceSummary {
334
340
  id: string;
335
341
  name: string;
336
342
  available: boolean;
337
343
  }
344
+ /** Query parameters accepted by Studio endpoints; list methods document their named filters. */
345
+ export type StudioQueryParams = Record<string, string | number | boolean | undefined>;
346
+ export interface StudioProjectListParams extends StudioQueryParams {
347
+ /** Case-insensitive title filter. */
348
+ q?: string;
349
+ page?: number;
350
+ /** Defaults to 50; maximum 100. */
351
+ pageSize?: number;
352
+ }
353
+ export interface StudioChapterListParams extends StudioQueryParams {
354
+ includeDeleted?: boolean;
355
+ }
356
+ export interface StudioClipListParams extends StudioQueryParams {
357
+ chapterId?: string;
358
+ includeDeleted?: boolean;
359
+ page?: number;
360
+ /** Defaults to 100; maximum 400. */
361
+ pageSize?: number;
362
+ }
363
+ export interface StudioFileListParams extends StudioQueryParams {
364
+ /** Omit to list personal files. */
365
+ projectId?: string;
366
+ /** Case-insensitive name filter. */
367
+ q?: string;
368
+ offset?: number;
369
+ /** Defaults to 100; maximum 500. Continue with `nextOffset`. */
370
+ limit?: number;
371
+ }
package/dist/studio.d.ts CHANGED
@@ -1,83 +1,174 @@
1
1
  import type { BreezeBlueClient } from "./client.js";
2
2
  import type { RequestOptions } from "./types.js";
3
3
  import type * as Types from "./studio-types.js";
4
+ /** Convert seconds to 48 kHz Studio timeline frames, rounding half away from zero. */
4
5
  export declare function secondsToFrames(seconds: number): number;
6
+ /** Convert 48 kHz Studio timeline frames to seconds. */
5
7
  export declare function framesToSeconds(frames: number): number;
6
8
  export declare class StudioProjectsResource {
7
9
  private client;
8
10
  constructor(client: BreezeBlueClient);
9
- list(params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectList>;
10
- create(body: Types.StudioProjectCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
11
- importProject(body: Types.StudioProjectImport, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
12
- get(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
13
- update(projectId: string, body: Types.StudioProjectPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
14
- delete(projectId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioDeleted>;
11
+ list(params?: Types.StudioProjectListParams, options?: RequestOptions): Promise<Types.StudioProjectList>;
12
+ create(body: Types.StudioProjectCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
13
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
14
+ create(body: Types.StudioProjectCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
15
+ importProject(body: Types.StudioProjectImport, options?: RequestOptions): Promise<Types.StudioProjectResult>;
16
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
17
+ importProject(body: Types.StudioProjectImport, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
18
+ get(projectId: string, options?: RequestOptions): Promise<Types.StudioProjectResult>;
19
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
20
+ get(projectId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
21
+ update(projectId: string, body: Types.StudioProjectPatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
22
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
23
+ update(projectId: string, body: Types.StudioProjectPatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
24
+ delete(projectId: string, body: Types.StudioEdit, options?: RequestOptions): Promise<Types.StudioDeleted>;
25
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
26
+ delete(projectId: string, body: Types.StudioEdit, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioDeleted>;
15
27
  }
16
28
  export declare class StudioChaptersResource {
17
29
  private client;
18
30
  constructor(client: BreezeBlueClient);
19
- list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioChapterList>;
20
- create(projectId: string, body: Types.StudioChapterCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
21
- reorder(projectId: string, body: Types.StudioReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
22
- get(projectId: string, chapterId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioChapterResult>;
23
- update(projectId: string, chapterId: string, body: Types.StudioChapterPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
24
- delete(projectId: string, chapterId: string, body: Types.StudioChapterDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
25
- restore(projectId: string, chapterId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
31
+ list(projectId: string, params?: Types.StudioChapterListParams, options?: RequestOptions): Promise<Types.StudioChapterList>;
32
+ create(projectId: string, body: Types.StudioChapterCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
33
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
34
+ create(projectId: string, body: Types.StudioChapterCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
35
+ reorder(projectId: string, body: Types.StudioReorder, options?: RequestOptions): Promise<Types.StudioProjectResult>;
36
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
37
+ reorder(projectId: string, body: Types.StudioReorder, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
38
+ get(projectId: string, chapterId: string, options?: RequestOptions): Promise<Types.StudioChapterResult>;
39
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
40
+ get(projectId: string, chapterId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioChapterResult>;
41
+ update(projectId: string, chapterId: string, body: Types.StudioChapterPatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
42
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
43
+ update(projectId: string, chapterId: string, body: Types.StudioChapterPatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
44
+ delete(projectId: string, chapterId: string, body: Types.StudioChapterDelete, options?: RequestOptions): Promise<Types.StudioProjectResult>;
45
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
46
+ delete(projectId: string, chapterId: string, body: Types.StudioChapterDelete, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
47
+ restore(projectId: string, chapterId: string, body: Types.StudioEdit, options?: RequestOptions): Promise<Types.StudioProjectResult>;
48
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
49
+ restore(projectId: string, chapterId: string, body: Types.StudioEdit, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
26
50
  }
27
51
  export declare class StudioClipsResource {
28
52
  private client;
29
53
  constructor(client: BreezeBlueClient);
30
- list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioClipList>;
31
- create(projectId: string, body: Types.StudioClipCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
32
- batchCreate(projectId: string, body: Types.StudioClipBatchCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
33
- batchUpdate(projectId: string, body: Types.StudioClipBatchPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
34
- bulkDelete(projectId: string, body: Types.StudioClipBulkDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
35
- reorder(projectId: string, body: Types.StudioClipReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
36
- move(projectId: string, body: Types.StudioClipMove, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
37
- get(projectId: string, clipId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioClipResult>;
38
- update(projectId: string, clipId: string, body: Types.StudioClipPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
39
- delete(projectId: string, clipId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
54
+ list(projectId: string, params?: Types.StudioClipListParams, options?: RequestOptions): Promise<Types.StudioClipList>;
55
+ create(projectId: string, body: Types.StudioClipCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
56
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
57
+ create(projectId: string, body: Types.StudioClipCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
58
+ batchCreate(projectId: string, body: Types.StudioClipBatchCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
59
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
60
+ batchCreate(projectId: string, body: Types.StudioClipBatchCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
61
+ batchUpdate(projectId: string, body: Types.StudioClipBatchPatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
62
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
63
+ batchUpdate(projectId: string, body: Types.StudioClipBatchPatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
64
+ bulkDelete(projectId: string, body: Types.StudioClipBulkDelete, options?: RequestOptions): Promise<Types.StudioProjectResult>;
65
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
66
+ bulkDelete(projectId: string, body: Types.StudioClipBulkDelete, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
67
+ reorder(projectId: string, body: Types.StudioClipReorder, options?: RequestOptions): Promise<Types.StudioProjectResult>;
68
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
69
+ reorder(projectId: string, body: Types.StudioClipReorder, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
70
+ move(projectId: string, body: Types.StudioClipMove, options?: RequestOptions): Promise<Types.StudioProjectResult>;
71
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
72
+ move(projectId: string, body: Types.StudioClipMove, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
73
+ get(projectId: string, clipId: string, options?: RequestOptions): Promise<Types.StudioClipResult>;
74
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
75
+ get(projectId: string, clipId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioClipResult>;
76
+ update(projectId: string, clipId: string, body: Types.StudioClipPatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
77
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
78
+ update(projectId: string, clipId: string, body: Types.StudioClipPatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
79
+ delete(projectId: string, clipId: string, body: Types.StudioEdit, options?: RequestOptions): Promise<Types.StudioProjectResult>;
80
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
81
+ delete(projectId: string, clipId: string, body: Types.StudioEdit, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
40
82
  }
41
83
  export declare class StudioTracksResource {
42
84
  private client;
43
85
  constructor(client: BreezeBlueClient);
44
- list(projectId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioTrackList>;
45
- create(projectId: string, body: Types.StudioTrackCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
46
- reorder(projectId: string, body: Types.StudioReorder, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
47
- get(projectId: string, trackId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioTrackResult>;
48
- update(projectId: string, trackId: string, body: Types.StudioTrackPatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
49
- delete(projectId: string, trackId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
86
+ list(projectId: string, options?: RequestOptions): Promise<Types.StudioTrackList>;
87
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
88
+ list(projectId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioTrackList>;
89
+ create(projectId: string, body: Types.StudioTrackCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
90
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
91
+ create(projectId: string, body: Types.StudioTrackCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
92
+ reorder(projectId: string, body: Types.StudioReorder, options?: RequestOptions): Promise<Types.StudioProjectResult>;
93
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
94
+ reorder(projectId: string, body: Types.StudioReorder, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
95
+ get(projectId: string, trackId: string, options?: RequestOptions): Promise<Types.StudioTrackResult>;
96
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
97
+ get(projectId: string, trackId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioTrackResult>;
98
+ update(projectId: string, trackId: string, body: Types.StudioTrackPatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
99
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
100
+ update(projectId: string, trackId: string, body: Types.StudioTrackPatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
101
+ delete(projectId: string, trackId: string, body: Types.StudioEdit, options?: RequestOptions): Promise<Types.StudioProjectResult>;
102
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
103
+ delete(projectId: string, trackId: string, body: Types.StudioEdit, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
50
104
  }
51
105
  export declare class StudioInstancesResource {
52
106
  private client;
53
107
  constructor(client: BreezeBlueClient);
54
- list(projectId: string, trackId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioInstanceList>;
55
- create(projectId: string, trackId: string, body: Types.StudioInstanceCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
56
- get(projectId: string, trackId: string, instanceId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioInstanceResult>;
57
- update(projectId: string, trackId: string, instanceId: string, body: Types.StudioInstancePatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
58
- delete(projectId: string, trackId: string, instanceId: string, body: Types.StudioEdit, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioProjectResult>;
108
+ list(projectId: string, trackId: string, options?: RequestOptions): Promise<Types.StudioInstanceList>;
109
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
110
+ list(projectId: string, trackId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioInstanceList>;
111
+ create(projectId: string, trackId: string, body: Types.StudioInstanceCreate, options?: RequestOptions): Promise<Types.StudioProjectResult>;
112
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
113
+ create(projectId: string, trackId: string, body: Types.StudioInstanceCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
114
+ get(projectId: string, trackId: string, instanceId: string, options?: RequestOptions): Promise<Types.StudioInstanceResult>;
115
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
116
+ get(projectId: string, trackId: string, instanceId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioInstanceResult>;
117
+ update(projectId: string, trackId: string, instanceId: string, body: Types.StudioInstancePatch, options?: RequestOptions): Promise<Types.StudioProjectResult>;
118
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
119
+ update(projectId: string, trackId: string, instanceId: string, body: Types.StudioInstancePatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
120
+ delete(projectId: string, trackId: string, instanceId: string, body: Types.StudioEdit, options?: RequestOptions): Promise<Types.StudioProjectResult>;
121
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
122
+ delete(projectId: string, trackId: string, instanceId: string, body: Types.StudioEdit, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioProjectResult>;
59
123
  }
124
+ /**
125
+ * Studio audio materials (MP3 or WAV). `upload` runs the whole flow:
126
+ * `create` → `uploadUrl` → signed PUT → `complete` → `waitReady`.
127
+ */
60
128
  export declare class StudioFilesResource {
61
129
  private client;
62
130
  constructor(client: BreezeBlueClient);
63
- list(params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileList>;
64
- create(body: Types.StudioFileCreate, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
65
- get(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
66
- update(fileId: string, body: Types.StudioFilePatch, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
67
- delete(fileId: string, body: Types.StudioFileDelete, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioDeleted>;
68
- uploadUrl(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioUploadResult>;
69
- complete(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
70
- retry(fileId: string, params?: Record<string, string | number | boolean | undefined>, options?: RequestOptions): Promise<Types.StudioFileView>;
131
+ list(params?: Types.StudioFileListParams, options?: RequestOptions): Promise<Types.StudioFileList>;
132
+ create(body: Types.StudioFileCreate, options?: RequestOptions): Promise<Types.StudioFileView>;
133
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
134
+ create(body: Types.StudioFileCreate, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioFileView>;
135
+ get(fileId: string, options?: RequestOptions): Promise<Types.StudioFileView>;
136
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
137
+ get(fileId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioFileView>;
138
+ update(fileId: string, body: Types.StudioFilePatch, options?: RequestOptions): Promise<Types.StudioFileView>;
139
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
140
+ update(fileId: string, body: Types.StudioFilePatch, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioFileView>;
141
+ delete(fileId: string, body: Types.StudioFileDelete, options?: RequestOptions): Promise<Types.StudioDeleted>;
142
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
143
+ delete(fileId: string, body: Types.StudioFileDelete, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioDeleted>;
144
+ uploadUrl(fileId: string, options?: RequestOptions): Promise<Types.StudioUploadResult>;
145
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
146
+ uploadUrl(fileId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioUploadResult>;
147
+ complete(fileId: string, options?: RequestOptions): Promise<Types.StudioFileView>;
148
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
149
+ complete(fileId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioFileView>;
150
+ retry(fileId: string, options?: RequestOptions): Promise<Types.StudioFileView>;
151
+ /** @deprecated This endpoint takes no query parameters; pass request options as the last argument. */
152
+ retry(fileId: string, params: Types.StudioQueryParams | undefined, options?: RequestOptions): Promise<Types.StudioFileView>;
153
+ /**
154
+ * Poll until the file is `ready`. Rejects with `BreezeBlueStudioFileError`
155
+ * when processing fails or is still running after `timeout` milliseconds.
156
+ */
71
157
  waitReady(fileId: string, options?: {
72
158
  timeout?: number;
73
159
  pollInterval?: number;
74
160
  signal?: AbortSignal;
75
161
  }): Promise<Types.StudioFileView>;
162
+ /**
163
+ * Upload an MP3 or WAV blob and, unless `wait` is false, wait until it is ready.
164
+ * Reusing `operationId` with identical input resumes the same file.
165
+ */
76
166
  upload(file: Blob, input: {
77
167
  operationId: string;
78
168
  name: string;
79
169
  projectId?: string;
80
170
  wait?: boolean;
171
+ waitTimeout?: number;
81
172
  }, options?: RequestOptions): Promise<Types.StudioFileView>;
82
173
  }
83
174
  export declare class StudioResource {
package/dist/studio.js CHANGED
@@ -1,9 +1,21 @@
1
+ import { BreezeBlueConfigurationError, BreezeBlueStudioFileError } from "./errors.js";
2
+ /** Convert seconds to 48 kHz Studio timeline frames, rounding half away from zero. */
1
3
  export function secondsToFrames(seconds) {
2
4
  if (!Number.isFinite(seconds))
3
5
  throw new Error("seconds must be finite");
4
6
  return Math.sign(seconds) * Math.round(Math.abs(seconds) * 48000);
5
7
  }
8
+ /** Convert 48 kHz Studio timeline frames to seconds. */
6
9
  export function framesToSeconds(frames) { return frames / 48000; }
10
+ /**
11
+ * Methods without query parameters take request options last. The 0.20.0
12
+ * `(…, params, options)` form keeps working when options are passed third.
13
+ */
14
+ function requestArgs(paramsOrOptions, legacyOptions) {
15
+ return legacyOptions === undefined
16
+ ? [undefined, paramsOrOptions]
17
+ : [paramsOrOptions, legacyOptions];
18
+ }
7
19
  export class StudioProjectsResource {
8
20
  client;
9
21
  constructor(client) {
@@ -12,19 +24,24 @@ export class StudioProjectsResource {
12
24
  list(params, options) {
13
25
  return this.client.requestJson("GET", `/v1/studio/projects`, params, undefined, options);
14
26
  }
15
- create(body, params, options) {
27
+ create(body, paramsOrOptions, legacyOptions) {
28
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
16
29
  return this.client.requestJson("POST", `/v1/studio/projects`, params, body, options);
17
30
  }
18
- importProject(body, params, options) {
31
+ importProject(body, paramsOrOptions, legacyOptions) {
32
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
19
33
  return this.client.requestJson("POST", `/v1/studio/projects/import`, params, body, options);
20
34
  }
21
- get(projectId, params, options) {
35
+ get(projectId, paramsOrOptions, legacyOptions) {
36
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
22
37
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, undefined, options);
23
38
  }
24
- update(projectId, body, params, options) {
39
+ update(projectId, body, paramsOrOptions, legacyOptions) {
40
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
25
41
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, body, options);
26
42
  }
27
- delete(projectId, body, params, options) {
43
+ delete(projectId, body, paramsOrOptions, legacyOptions) {
44
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
28
45
  return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}`, params, body, options);
29
46
  }
30
47
  }
@@ -36,22 +53,28 @@ export class StudioChaptersResource {
36
53
  list(projectId, params, options) {
37
54
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters`, params, undefined, options);
38
55
  }
39
- create(projectId, body, params, options) {
56
+ create(projectId, body, paramsOrOptions, legacyOptions) {
57
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
40
58
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters`, params, body, options);
41
59
  }
42
- reorder(projectId, body, params, options) {
60
+ reorder(projectId, body, paramsOrOptions, legacyOptions) {
61
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
43
62
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/reorder`, params, body, options);
44
63
  }
45
- get(projectId, chapterId, params, options) {
64
+ get(projectId, chapterId, paramsOrOptions, legacyOptions) {
65
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
46
66
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, undefined, options);
47
67
  }
48
- update(projectId, chapterId, body, params, options) {
68
+ update(projectId, chapterId, body, paramsOrOptions, legacyOptions) {
69
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
49
70
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, body, options);
50
71
  }
51
- delete(projectId, chapterId, body, params, options) {
72
+ delete(projectId, chapterId, body, paramsOrOptions, legacyOptions) {
73
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
52
74
  return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}`, params, body, options);
53
75
  }
54
- restore(projectId, chapterId, body, params, options) {
76
+ restore(projectId, chapterId, body, paramsOrOptions, legacyOptions) {
77
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
55
78
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/chapters/${encodeURIComponent(chapterId)}/restore`, params, body, options);
56
79
  }
57
80
  }
@@ -63,31 +86,40 @@ export class StudioClipsResource {
63
86
  list(projectId, params, options) {
64
87
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips`, params, undefined, options);
65
88
  }
66
- create(projectId, body, params, options) {
89
+ create(projectId, body, paramsOrOptions, legacyOptions) {
90
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
67
91
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips`, params, body, options);
68
92
  }
69
- batchCreate(projectId, body, params, options) {
93
+ batchCreate(projectId, body, paramsOrOptions, legacyOptions) {
94
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
70
95
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/batch`, params, body, options);
71
96
  }
72
- batchUpdate(projectId, body, params, options) {
97
+ batchUpdate(projectId, body, paramsOrOptions, legacyOptions) {
98
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
73
99
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/batch`, params, body, options);
74
100
  }
75
- bulkDelete(projectId, body, params, options) {
101
+ bulkDelete(projectId, body, paramsOrOptions, legacyOptions) {
102
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
76
103
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/bulk-delete`, params, body, options);
77
104
  }
78
- reorder(projectId, body, params, options) {
105
+ reorder(projectId, body, paramsOrOptions, legacyOptions) {
106
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
79
107
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/reorder`, params, body, options);
80
108
  }
81
- move(projectId, body, params, options) {
109
+ move(projectId, body, paramsOrOptions, legacyOptions) {
110
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
82
111
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/move`, params, body, options);
83
112
  }
84
- get(projectId, clipId, params, options) {
113
+ get(projectId, clipId, paramsOrOptions, legacyOptions) {
114
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
85
115
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, undefined, options);
86
116
  }
87
- update(projectId, clipId, body, params, options) {
117
+ update(projectId, clipId, body, paramsOrOptions, legacyOptions) {
118
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
88
119
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, body, options);
89
120
  }
90
- delete(projectId, clipId, body, params, options) {
121
+ delete(projectId, clipId, body, paramsOrOptions, legacyOptions) {
122
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
91
123
  return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/clips/${encodeURIComponent(clipId)}`, params, body, options);
92
124
  }
93
125
  }
@@ -96,22 +128,28 @@ export class StudioTracksResource {
96
128
  constructor(client) {
97
129
  this.client = client;
98
130
  }
99
- list(projectId, params, options) {
131
+ list(projectId, paramsOrOptions, legacyOptions) {
132
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
100
133
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks`, params, undefined, options);
101
134
  }
102
- create(projectId, body, params, options) {
135
+ create(projectId, body, paramsOrOptions, legacyOptions) {
136
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
103
137
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks`, params, body, options);
104
138
  }
105
- reorder(projectId, body, params, options) {
139
+ reorder(projectId, body, paramsOrOptions, legacyOptions) {
140
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
106
141
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/reorder`, params, body, options);
107
142
  }
108
- get(projectId, trackId, params, options) {
143
+ get(projectId, trackId, paramsOrOptions, legacyOptions) {
144
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
109
145
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, undefined, options);
110
146
  }
111
- update(projectId, trackId, body, params, options) {
147
+ update(projectId, trackId, body, paramsOrOptions, legacyOptions) {
148
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
112
149
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, body, options);
113
150
  }
114
- delete(projectId, trackId, body, params, options) {
151
+ delete(projectId, trackId, body, paramsOrOptions, legacyOptions) {
152
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
115
153
  return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}`, params, body, options);
116
154
  }
117
155
  }
@@ -120,22 +158,31 @@ export class StudioInstancesResource {
120
158
  constructor(client) {
121
159
  this.client = client;
122
160
  }
123
- list(projectId, trackId, params, options) {
161
+ list(projectId, trackId, paramsOrOptions, legacyOptions) {
162
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
124
163
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances`, params, undefined, options);
125
164
  }
126
- create(projectId, trackId, body, params, options) {
165
+ create(projectId, trackId, body, paramsOrOptions, legacyOptions) {
166
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
127
167
  return this.client.requestJson("POST", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances`, params, body, options);
128
168
  }
129
- get(projectId, trackId, instanceId, params, options) {
169
+ get(projectId, trackId, instanceId, paramsOrOptions, legacyOptions) {
170
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
130
171
  return this.client.requestJson("GET", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, undefined, options);
131
172
  }
132
- update(projectId, trackId, instanceId, body, params, options) {
173
+ update(projectId, trackId, instanceId, body, paramsOrOptions, legacyOptions) {
174
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
133
175
  return this.client.requestJson("PATCH", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, body, options);
134
176
  }
135
- delete(projectId, trackId, instanceId, body, params, options) {
177
+ delete(projectId, trackId, instanceId, body, paramsOrOptions, legacyOptions) {
178
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
136
179
  return this.client.requestJson("DELETE", `/v1/studio/projects/${encodeURIComponent(projectId)}/tracks/${encodeURIComponent(trackId)}/instances/${encodeURIComponent(instanceId)}`, params, body, options);
137
180
  }
138
181
  }
182
+ /**
183
+ * Studio audio materials (MP3 or WAV). `upload` runs the whole flow:
184
+ * `create` → `uploadUrl` → signed PUT → `complete` → `waitReady`.
185
+ */
139
186
  export class StudioFilesResource {
140
187
  client;
141
188
  constructor(client) {
@@ -144,55 +191,70 @@ export class StudioFilesResource {
144
191
  list(params, options) {
145
192
  return this.client.requestJson("GET", `/v1/studio/files`, params, undefined, options);
146
193
  }
147
- create(body, params, options) {
194
+ create(body, paramsOrOptions, legacyOptions) {
195
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
148
196
  return this.client.requestJson("POST", `/v1/studio/files`, params, body, options);
149
197
  }
150
- get(fileId, params, options) {
198
+ get(fileId, paramsOrOptions, legacyOptions) {
199
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
151
200
  return this.client.requestJson("GET", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, undefined, options);
152
201
  }
153
- update(fileId, body, params, options) {
202
+ update(fileId, body, paramsOrOptions, legacyOptions) {
203
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
154
204
  return this.client.requestJson("PATCH", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, body, options);
155
205
  }
156
- delete(fileId, body, params, options) {
206
+ delete(fileId, body, paramsOrOptions, legacyOptions) {
207
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
157
208
  return this.client.requestJson("DELETE", `/v1/studio/files/${encodeURIComponent(fileId)}`, params, body, options);
158
209
  }
159
- uploadUrl(fileId, params, options) {
210
+ uploadUrl(fileId, paramsOrOptions, legacyOptions) {
211
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
160
212
  return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/upload`, params, undefined, options);
161
213
  }
162
- complete(fileId, params, options) {
214
+ complete(fileId, paramsOrOptions, legacyOptions) {
215
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
163
216
  return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/complete`, params, undefined, options);
164
217
  }
165
- retry(fileId, params, options) {
218
+ retry(fileId, paramsOrOptions, legacyOptions) {
219
+ const [params, options] = requestArgs(paramsOrOptions, legacyOptions);
166
220
  return this.client.requestJson("POST", `/v1/studio/files/${encodeURIComponent(fileId)}/retry`, params, undefined, options);
167
221
  }
222
+ /**
223
+ * Poll until the file is `ready`. Rejects with `BreezeBlueStudioFileError`
224
+ * when processing fails or is still running after `timeout` milliseconds.
225
+ */
168
226
  async waitReady(fileId, options = {}) {
169
227
  const deadline = Date.now() + (options.timeout ?? 300000);
170
228
  while (true) {
171
229
  options.signal?.throwIfAborted();
172
- const value = await this.get(fileId, undefined, { signal: options.signal });
230
+ const value = await this.get(fileId, { signal: options.signal });
173
231
  if (value.status === "ready")
174
232
  return value;
175
233
  if (value.status === "failed")
176
- throw new Error(value.errorMessage ?? "Studio file processing failed");
234
+ throw new BreezeBlueStudioFileError(value.errorMessage ?? "Studio file processing failed", value);
177
235
  if (Date.now() >= deadline)
178
- throw new Error("Studio file is still processing; query the same file ID to resume");
236
+ throw new BreezeBlueStudioFileError("Studio file is still processing; query the same file ID to resume", value);
179
237
  await new Promise(resolve => setTimeout(resolve, Math.max(100, Math.min(options.pollInterval ?? 1000, deadline - Date.now()))));
180
238
  }
181
239
  }
240
+ /**
241
+ * Upload an MP3 or WAV blob and, unless `wait` is false, wait until it is ready.
242
+ * Reusing `operationId` with identical input resumes the same file.
243
+ */
182
244
  async upload(file, input, options = {}) {
183
245
  const mimeType = input.name.toLowerCase().endsWith(".mp3") ? "audio/mpeg" : input.name.toLowerCase().endsWith(".wav") ? "audio/wav" : null;
184
246
  if (!mimeType)
185
- throw new Error("Studio accepts MP3 or WAV files");
186
- let value = await this.create({ operationId: input.operationId, name: input.name, projectId: input.projectId, sizeBytes: file.size, mimeType }, undefined, options);
247
+ throw new BreezeBlueConfigurationError("Studio accepts MP3 or WAV files");
248
+ let value = await this.create({ operationId: input.operationId, name: input.name, projectId: input.projectId, sizeBytes: file.size, mimeType }, options);
187
249
  if (value.status === "uploading") {
188
- const signed = await this.uploadUrl(value.id, undefined, options);
250
+ const signed = await this.uploadUrl(value.id, options);
189
251
  // Never use the API request helper for a signed storage URL.
190
252
  const response = await this.client.fetch(signed.uploadUrl, { method: "PUT", headers: signed.headers, body: file, credentials: "omit", redirect: "error", signal: options.signal });
191
253
  if (!response.ok)
192
- throw new Error(`Studio upload failed: ${response.status}`);
193
- value = await this.complete(value.id, undefined, options);
254
+ throw new BreezeBlueStudioFileError(`Studio upload failed with HTTP ${response.status}`, value);
255
+ value = await this.complete(value.id, options);
194
256
  }
195
- return input.wait === false ? value : this.waitReady(value.id, { signal: options.signal });
257
+ return input.wait === false ? value : this.waitReady(value.id, { timeout: input.waitTimeout, signal: options.signal });
196
258
  }
197
259
  }
198
260
  export class StudioResource {
package/dist/types.d.ts CHANGED
@@ -23,7 +23,6 @@ export interface AudioRequestOptions extends RequestOptions {
23
23
  outputFormat?: string;
24
24
  }
25
25
  export interface StreamTextToSpeechOptions extends AudioRequestOptions {
26
- optimizeStreamingLatency?: number;
27
26
  enableLogging?: boolean;
28
27
  }
29
28
  export type BreezeBlueWebSocketConstructor = new (url: string, protocols?: string | string[]) => BreezeBlueWebSocket;
@@ -42,9 +41,7 @@ export interface RealtimeTextToSpeechSessionRequest {
42
41
  modelId?: string;
43
42
  languageCode?: string;
44
43
  instructions?: string;
45
- voiceSettings?: {
46
- guidanceScale?: number | null;
47
- };
44
+ voiceSettings?: Pick<TtsVoiceSettings, "guidanceScale" | "useSpeakerBoost">;
48
45
  inactivityTimeoutSeconds?: number;
49
46
  enableLogging?: boolean;
50
47
  }
@@ -226,18 +223,15 @@ export interface RealtimeTextToSpeechAudioMessage {
226
223
  audio: Uint8Array;
227
224
  }
228
225
  export type RealtimeTextToSpeechMessage = RealtimeTextToSpeechEvent | RealtimeTextToSpeechAudioMessage;
229
- export interface VoiceSettings {
230
- stability?: number;
231
- similarityBoost?: number;
232
- style?: number;
226
+ /** Per-request controls. */
227
+ export interface TtsVoiceSettings {
228
+ /** Generation guidance strength (1–10). Omitted or null uses the default 1. */
229
+ guidanceScale?: number | null;
230
+ /** Default false. Ignored with non-empty instructions and guidanceScale > 1; otherwise instructions are not used. */
233
231
  useSpeakerBoost?: boolean;
234
- /** Request-only, pitch-preserving HTTP TTS speed (0.5–2.0). Omitted means 1.0. */
232
+ /** Pitch-preserving speed (0.5–2.0). */
235
233
  speed?: number;
236
- guidanceScale?: number | null;
237
- }
238
- /** Request-only HTTP TTS settings. Volume is a linear amplitude multiplier. */
239
- export interface TtsVoiceSettings extends VoiceSettings {
240
- /** Linear amplitude multiplier (0.01–2.0); omitted means 1.0. */
234
+ /** Linear amplitude multiplier (0.01–2.0). */
241
235
  volume?: number;
242
236
  }
243
237
  export interface PronunciationDictionaryLocator {
@@ -250,14 +244,6 @@ export interface TextToSpeechRequest {
250
244
  languageCode?: string;
251
245
  instructions?: string;
252
246
  voiceSettings?: TtsVoiceSettings;
253
- seed?: number;
254
- pronunciationDictionaryLocators?: PronunciationDictionaryLocator[];
255
- previousText?: string;
256
- nextText?: string;
257
- previousRequestIds?: string[];
258
- nextRequestIds?: string[];
259
- applyTextNormalization?: string;
260
- applyLanguageTextNormalization?: boolean;
261
247
  }
262
248
  export interface TtsEnhanceRequest {
263
249
  instruction: string;
@@ -315,7 +301,6 @@ export interface Voice {
315
301
  tags: string[];
316
302
  isFavorited: boolean;
317
303
  previewUrl?: string | null;
318
- settings: Required<VoiceSettings>;
319
304
  description?: string | null;
320
305
  createdAtUnix?: number | null;
321
306
  primaryCategoryCode?: string | null;
@@ -430,10 +415,6 @@ export interface VoiceDesignRequest {
430
415
  text?: string;
431
416
  modelId?: string;
432
417
  languageCode?: VoiceLanguageCode;
433
- autoGenerateText?: boolean;
434
- loudness?: number;
435
- quality?: number;
436
- seed?: number;
437
418
  guidanceScale?: number | null;
438
419
  previewCount?: number;
439
420
  }
@@ -528,7 +509,6 @@ export interface SaveVoiceRequest {
528
509
  tags?: string[];
529
510
  primaryCategoryCode?: string;
530
511
  visibility?: "private" | "public" | string;
531
- playedNotSelectedVoiceIds?: string[];
532
512
  languageCode: VoiceLanguageCode;
533
513
  gender?: VoiceGender | null;
534
514
  age?: VoiceAge | null;
@@ -588,6 +568,20 @@ export interface Balance {
588
568
  topups: BalanceTopup[];
589
569
  [key: string]: unknown;
590
570
  }
571
+ export interface Entitlements {
572
+ planCode: string;
573
+ status: string;
574
+ billingInterval: string | null;
575
+ cancelAtPeriodEnd: boolean;
576
+ currentPeriodStart: string | null;
577
+ currentPeriodEnd: string | null;
578
+ monthlyCreativeCredits: number;
579
+ savedVoiceLimit: number;
580
+ savedProjectLimit: number;
581
+ maxConcurrentGenerations: number;
582
+ studioLongFormAccess: boolean;
583
+ commercialUseAllowed: boolean;
584
+ }
591
585
  export interface CurrentApiKey {
592
586
  id: string;
593
587
  name: string;
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const SDK_VERSION = "0.20.0";
1
+ export declare const SDK_VERSION = "0.21.0";
2
2
  export declare const SDK_NAME = "@breeze.blue/sdk";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const SDK_VERSION = "0.20.0";
1
+ export const SDK_VERSION = "0.21.0";
2
2
  export const SDK_NAME = "@breeze.blue/sdk";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breeze.blue/sdk",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "ESM-first TypeScript SDK for the Breeze Blue Developer API.",
5
5
  "license": "MIT",
6
6
  "author": "Breeze Blue <support@breezeblue.ai>",