@@ -7,15 +7,23 @@ import { requestWithRetries } from "./core/retry";
77import { DiffioApiError , DiffioTimeoutError } from "./errors" ;
88import {
99 createAudioIsolationResult ,
10+ parseAccountSettingsResponse ,
11+ parseApiKeyResponse ,
12+ parseApiKeysListResponse ,
1013 parseCreateGenerationResponse ,
1114 parseCreateProjectResponse ,
1215 parseGenerationDownloadResponse ,
1316 parseGenerationProgressResponse ,
1417 parseListProjectGenerationsResponse ,
1518 parseListProjectsResponse ,
19+ parseUsageSummaryResponse ,
20+ parseWebhookConfigureResponse ,
1621 parseWebhookTestEventResponse
1722} from "./api/serialization" ;
1823import type {
24+ AccountSettingsResponse ,
25+ ApiKeyResponse ,
26+ ApiKeysListResponse ,
1927 AudioIsolationResult ,
2028 CreateGenerationResponse ,
2129 CreateProjectResponse ,
@@ -24,17 +32,29 @@ import type {
2432 ListProjectGenerationsResponse ,
2533 ListProjectsResponse ,
2634 RestoreMetadata ,
35+ UsageSummaryResponse ,
36+ WebhookConfigureResponse ,
2737 WebhookTestEventResponse
2838} from "./api/types" ;
29- import { AudioIsolationClient , GenerationsClient , ProjectsClient , WebhooksClient } from "./api/resources" ;
39+ import {
40+ AccountClient ,
41+ ApiKeysClient ,
42+ AudioIsolationClient ,
43+ GenerationsClient ,
44+ ProjectsClient ,
45+ UsageClient ,
46+ WebhooksClient
47+ } from "./api/resources" ;
3048import { lookup as lookupMimeType } from "mime-types" ;
3149
3250const DEFAULT_BASE_URL = "https://api.diffio.ai" ;
3351const API_PREFIX = "v1" ;
3452const MODEL_ENDPOINTS : Record < string , string > = {
3553 "diffio-2" : "diffio-2.0-generation" ,
3654 "diffio-2-flash" : "diffio-2.0-flash-generation" ,
37- "diffio-3" : "diffio-3.0-generation"
55+ "diffio-3" : "diffio-3.0-generation" ,
56+ "diffio-3.4" : "diffio-3.4-generation" ,
57+ "diffio-3.5" : "diffio-3.5-generation"
3858} ;
3959const DEFAULT_RETRY_STATUS_CODES = [ 408 , 429 , 500 , 502 , 503 , 504 ] ;
4060const DEFAULT_RETRY_BACKOFF = 0.5 ;
@@ -58,6 +78,9 @@ export class DiffioClient {
5878 public readonly audioIsolation : AudioIsolationClient ;
5979 public readonly generations : GenerationsClient ;
6080 public readonly projects : ProjectsClient ;
81+ public readonly account : AccountClient ;
82+ public readonly apiKeys : ApiKeysClient ;
83+ public readonly usage : UsageClient ;
6184 public readonly webhooks : WebhooksClient ;
6285
6386 constructor ( options : DiffioClient . Options = { } ) {
@@ -71,6 +94,9 @@ export class DiffioClient {
7194 this . audioIsolation = new AudioIsolationClient ( this ) ;
7295 this . generations = new GenerationsClient ( this ) ;
7396 this . projects = new ProjectsClient ( this ) ;
97+ this . account = new AccountClient ( this ) ;
98+ this . apiKeys = new ApiKeysClient ( this ) ;
99+ this . usage = new UsageClient ( this ) ;
74100 this . webhooks = new WebhooksClient ( this ) ;
75101 }
76102
@@ -279,15 +305,122 @@ export class DiffioClient {
279305 const { generationId, apiProjectId, downloadType, requestOptions } = options ;
280306 const payload : Record < string , unknown > = { generationId, apiProjectId } ;
281307 if ( downloadType != null ) {
282- if ( downloadType !== "audio" && downloadType !== "video" ) {
283- throw new DiffioApiError ( "downloadType must be audio or video " ) ;
308+ if ( downloadType !== "audio" && downloadType !== "video" && downloadType !== "transcript" ) {
309+ throw new DiffioApiError ( "downloadType must be audio, video, or transcript " ) ;
284310 }
285311 payload . downloadType = downloadType ;
286312 }
287313 const response = await this . _requestJson ( "POST" , "get_generation_download" , payload , requestOptions ) ;
288314 return parseGenerationDownloadResponse ( response ) ;
289315 }
290316
317+ async getAccountSettings ( options : {
318+ requestOptions ?: DiffioClient . RequestOptions ;
319+ } = { } ) : Promise < AccountSettingsResponse > {
320+ const response = await this . _requestJson ( "POST" , "account/settings/get" , { } , options . requestOptions ) ;
321+ return parseAccountSettingsResponse ( response ) ;
322+ }
323+
324+ async updateAccountSettings ( options : {
325+ billingPolicy : Record < string , unknown > ;
326+ requestOptions ?: DiffioClient . RequestOptions ;
327+ } ) : Promise < AccountSettingsResponse > {
328+ const { billingPolicy, requestOptions } = options ;
329+ if ( ! billingPolicy || typeof billingPolicy !== "object" || Array . isArray ( billingPolicy ) ) {
330+ throw new DiffioApiError ( "billingPolicy must be an object" ) ;
331+ }
332+ const response = await this . _requestJson ( "POST" , "account/settings/update" , { billingPolicy } , requestOptions ) ;
333+ return parseAccountSettingsResponse ( response ) ;
334+ }
335+
336+ async createApiKey ( options : {
337+ label : string ;
338+ scopes : string [ ] ;
339+ resourceBounds ?: Record < string , unknown > ;
340+ requestOptions ?: DiffioClient . RequestOptions ;
341+ } ) : Promise < ApiKeyResponse > {
342+ const { label, scopes, resourceBounds, requestOptions } = options ;
343+ if ( ! label ) {
344+ throw new DiffioApiError ( "label is required" ) ;
345+ }
346+ if ( ! Array . isArray ( scopes ) ) {
347+ throw new DiffioApiError ( "scopes must be an array" ) ;
348+ }
349+ const response = await this . _requestJson (
350+ "POST" ,
351+ "api_keys/create" ,
352+ { label, scopes, resourceBounds : resourceBounds ?? { } } ,
353+ requestOptions
354+ ) ;
355+ return parseApiKeyResponse ( response ) ;
356+ }
357+
358+ async listApiKeys ( options : { requestOptions ?: DiffioClient . RequestOptions } = { } ) : Promise < ApiKeysListResponse > {
359+ const response = await this . _requestJson ( "POST" , "api_keys/list" , { } , options . requestOptions ) ;
360+ return parseApiKeysListResponse ( response ) ;
361+ }
362+
363+ async rotateApiKey ( options : {
364+ keyId : string ;
365+ requestOptions ?: DiffioClient . RequestOptions ;
366+ } ) : Promise < ApiKeyResponse > {
367+ const { keyId, requestOptions } = options ;
368+ if ( ! keyId ) {
369+ throw new DiffioApiError ( "keyId is required" ) ;
370+ }
371+ const response = await this . _requestJson ( "POST" , "api_keys/rotate" , { keyId } , requestOptions ) ;
372+ return parseApiKeyResponse ( response ) ;
373+ }
374+
375+ async revokeApiKey ( options : {
376+ keyId : string ;
377+ requestOptions ?: DiffioClient . RequestOptions ;
378+ } ) : Promise < ApiKeyResponse > {
379+ const { keyId, requestOptions } = options ;
380+ if ( ! keyId ) {
381+ throw new DiffioApiError ( "keyId is required" ) ;
382+ }
383+ const response = await this . _requestJson ( "POST" , "api_keys/revoke" , { keyId } , requestOptions ) ;
384+ return parseApiKeyResponse ( response ) ;
385+ }
386+
387+ async getUsageSummary ( options : {
388+ apiKeyId ?: string ;
389+ requestOptions ?: DiffioClient . RequestOptions ;
390+ } = { } ) : Promise < UsageSummaryResponse > {
391+ const payload : Record < string , unknown > = { } ;
392+ if ( options . apiKeyId != null ) {
393+ payload . apiKeyId = options . apiKeyId ;
394+ }
395+ const response = await this . _requestJson ( "POST" , "usage/summary" , payload , options . requestOptions ) ;
396+ return parseUsageSummaryResponse ( response ) ;
397+ }
398+
399+ async configureWebhook ( options : {
400+ mode : string ;
401+ url : string ;
402+ eventTypes : string [ ] ;
403+ apiKeyId ?: string ;
404+ requestOptions ?: DiffioClient . RequestOptions ;
405+ } ) : Promise < WebhookConfigureResponse > {
406+ const { mode, url, eventTypes, apiKeyId, requestOptions } = options ;
407+ if ( ! WEBHOOK_MODES . includes ( mode ) ) {
408+ throw new DiffioApiError ( "mode must be test or live" ) ;
409+ }
410+ if ( ! url ) {
411+ throw new DiffioApiError ( "url is required" ) ;
412+ }
413+ if ( ! Array . isArray ( eventTypes ) || eventTypes . length === 0 ) {
414+ throw new DiffioApiError ( "eventTypes must be a non-empty array" ) ;
415+ }
416+ const payload : Record < string , unknown > = { mode, url, eventTypes } ;
417+ if ( apiKeyId != null ) {
418+ payload . apiKeyId = apiKeyId ;
419+ }
420+ const response = await this . _requestJson ( "POST" , "webhooks/configure" , payload , requestOptions ) ;
421+ return parseWebhookConfigureResponse ( response ) ;
422+ }
423+
291424 async sendWebhookTestEvent ( options : {
292425 eventType : string ;
293426 mode : string ;
@@ -817,7 +950,12 @@ function isNodeReadable(value: unknown): value is NodeJS.ReadableStream {
817950
818951async function createFileReadStream ( filePath : string ) : Promise < NodeJS . ReadableStream > {
819952 const fs = await import ( "node:fs" ) ;
820- return fs . createReadStream ( filePath ) ;
953+ const stream = fs . createReadStream ( filePath ) ;
954+ await new Promise < void > ( ( resolve , reject ) => {
955+ stream . once ( "open" , ( ) => resolve ( ) ) ;
956+ stream . once ( "error" , reject ) ;
957+ } ) ;
958+ return stream ;
821959}
822960
823961function getFileSize ( filePath : string ) : number {
0 commit comments