assemblyai 4.0.0-beta.0 → 4.0.0-beta.2
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 +92 -0
- package/dist/assemblyai.umd.js +26 -33
- package/dist/assemblyai.umd.min.js +1 -1
- package/dist/{index.browser.js → bun.mjs} +167 -303
- package/dist/deno.mjs +540 -0
- package/dist/fs/bun.d.ts +1 -0
- package/dist/fs/deno.d.ts +1 -0
- package/dist/fs/index.d.ts +1 -0
- package/dist/fs/node.d.ts +1 -0
- package/dist/index.cjs +11 -4
- package/dist/index.mjs +11 -4
- package/dist/node.cjs +549 -0
- package/dist/node.mjs +542 -0
- package/dist/services/realtime/service.d.ts +0 -2
- package/docs/compat.md +59 -0
- package/package.json +38 -11
- package/src/fs/bun.ts +8 -0
- package/src/fs/deno.ts +9 -0
- package/src/fs/index.ts +8 -0
- package/src/fs/node.ts +7 -0
- package/src/services/files/index.ts +2 -2
- package/src/services/realtime/service.ts +2 -2
- package/dist/browser/fs.d.ts +0 -6
- package/src/browser/fs.ts +0 -8
|
@@ -1,46 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
5
|
-
purpose with or without fee is hereby granted.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
9
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
14
|
-
***************************************************************************** */
|
|
15
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function __rest(s, e) {
|
|
19
|
-
var t = {};
|
|
20
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
21
|
-
t[p] = s[p];
|
|
22
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
23
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
24
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
25
|
-
t[p[i]] = s[p[i]];
|
|
26
|
-
}
|
|
27
|
-
return t;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
31
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
32
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
33
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
34
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
35
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
36
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
41
|
-
var e = new Error(message);
|
|
42
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
43
|
-
};
|
|
1
|
+
import { WritableStream } from '@swimburger/isomorphic-streams';
|
|
2
|
+
import WebSocket from 'isomorphic-ws';
|
|
44
3
|
|
|
45
4
|
/**
|
|
46
5
|
* Base class for services that communicate with the API.
|
|
@@ -53,39 +12,38 @@ class BaseService {
|
|
|
53
12
|
constructor(params) {
|
|
54
13
|
this.params = params;
|
|
55
14
|
}
|
|
56
|
-
fetch(input, init) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
throw new Error(json.error);
|
|
77
|
-
throw new Error(text);
|
|
15
|
+
async fetch(input, init) {
|
|
16
|
+
init = init ?? {};
|
|
17
|
+
init.headers = init.headers ?? {};
|
|
18
|
+
init.headers = {
|
|
19
|
+
Authorization: this.params.apiKey,
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
...init.headers,
|
|
22
|
+
};
|
|
23
|
+
if (!input.startsWith("http"))
|
|
24
|
+
input = this.params.baseUrl + input;
|
|
25
|
+
const response = await fetch(input, init);
|
|
26
|
+
if (response.status >= 400) {
|
|
27
|
+
let json;
|
|
28
|
+
const text = await response.text();
|
|
29
|
+
if (text) {
|
|
30
|
+
try {
|
|
31
|
+
json = JSON.parse(text);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* empty */
|
|
78
35
|
}
|
|
79
|
-
|
|
36
|
+
if (json?.error)
|
|
37
|
+
throw new Error(json.error);
|
|
38
|
+
throw new Error(text);
|
|
80
39
|
}
|
|
81
|
-
|
|
82
|
-
}
|
|
40
|
+
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
return response;
|
|
83
43
|
}
|
|
84
|
-
fetchJson(input, init) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return response.json();
|
|
88
|
-
});
|
|
44
|
+
async fetchJson(input, init) {
|
|
45
|
+
const response = await this.fetch(input, init);
|
|
46
|
+
return response.json();
|
|
89
47
|
}
|
|
90
48
|
}
|
|
91
49
|
|
|
@@ -125,66 +83,6 @@ class LemurService extends BaseService {
|
|
|
125
83
|
}
|
|
126
84
|
}
|
|
127
85
|
|
|
128
|
-
const {
|
|
129
|
-
ReadableStream,
|
|
130
|
-
ReadableStreamDefaultReader,
|
|
131
|
-
ReadableStreamBYOBReader,
|
|
132
|
-
ReadableStreamBYOBRequest,
|
|
133
|
-
ReadableByteStreamController,
|
|
134
|
-
ReadableStreamDefaultController,
|
|
135
|
-
TransformStream,
|
|
136
|
-
TransformStreamDefaultController,
|
|
137
|
-
WritableStream,
|
|
138
|
-
WritableStreamDefaultWriter,
|
|
139
|
-
WritableStreamDefaultController,
|
|
140
|
-
ByteLengthQueuingStrategy,
|
|
141
|
-
CountQueuingStrategy,
|
|
142
|
-
TextEncoderStream,
|
|
143
|
-
TextDecoderStream,
|
|
144
|
-
} = window;
|
|
145
|
-
|
|
146
|
-
// Polyfill to make ReadableStream async-iterable with for-await
|
|
147
|
-
// https://jakearchibald.com/2017/async-iterators-and-generators/#making-streams-iterate
|
|
148
|
-
if (!ReadableStream.prototype[Symbol.asyncIterator]) {
|
|
149
|
-
async function* streamAsyncIterator() {
|
|
150
|
-
// Get a lock on the stream
|
|
151
|
-
const reader = this.getReader();
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
while (true) {
|
|
155
|
-
// Read from the stream
|
|
156
|
-
const { done, value } = await reader.read();
|
|
157
|
-
// Exit if we're done
|
|
158
|
-
if (done) return;
|
|
159
|
-
// Else yield the chunk
|
|
160
|
-
yield value;
|
|
161
|
-
}
|
|
162
|
-
} finally {
|
|
163
|
-
reader.releaseLock();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
ReadableStream.prototype[Symbol.asyncIterator] = streamAsyncIterator;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// https://github.com/maxogden/websocket-stream/blob/48dc3ddf943e5ada668c31ccd94e9186f02fafbd/ws-fallback.js
|
|
171
|
-
|
|
172
|
-
var ws = null;
|
|
173
|
-
|
|
174
|
-
if (typeof WebSocket !== 'undefined') {
|
|
175
|
-
ws = WebSocket;
|
|
176
|
-
} else if (typeof MozWebSocket !== 'undefined') {
|
|
177
|
-
ws = MozWebSocket;
|
|
178
|
-
} else if (typeof global !== 'undefined') {
|
|
179
|
-
ws = global.WebSocket || global.MozWebSocket;
|
|
180
|
-
} else if (typeof window !== 'undefined') {
|
|
181
|
-
ws = window.WebSocket || window.MozWebSocket;
|
|
182
|
-
} else if (typeof self !== 'undefined') {
|
|
183
|
-
ws = self.WebSocket || self.MozWebSocket;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
var WebSocket$1 = ws;
|
|
187
|
-
|
|
188
86
|
var RealtimeErrorType;
|
|
189
87
|
(function (RealtimeErrorType) {
|
|
190
88
|
RealtimeErrorType[RealtimeErrorType["BadSampleRate"] = 4000] = "BadSampleRate";
|
|
@@ -229,14 +127,13 @@ class RealtimeError extends Error {
|
|
|
229
127
|
const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
|
|
230
128
|
class RealtimeService {
|
|
231
129
|
constructor(params) {
|
|
232
|
-
var _a, _b;
|
|
233
130
|
this.listeners = {};
|
|
234
|
-
this.realtimeUrl =
|
|
235
|
-
this.sampleRate =
|
|
131
|
+
this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
|
|
132
|
+
this.sampleRate = params.sampleRate ?? 16000;
|
|
236
133
|
this.wordBoost = params.wordBoost;
|
|
237
|
-
if ("apiKey" in params)
|
|
134
|
+
if ("apiKey" in params && params.apiKey)
|
|
238
135
|
this.apiKey = params.apiKey;
|
|
239
|
-
if ("token" in params)
|
|
136
|
+
if ("token" in params && params.token)
|
|
240
137
|
this.token = params.token;
|
|
241
138
|
if (!(this.apiKey || this.token)) {
|
|
242
139
|
throw new Error("API key or temporary token is required.");
|
|
@@ -269,34 +166,31 @@ class RealtimeService {
|
|
|
269
166
|
}
|
|
270
167
|
const url = this.connectionUrl();
|
|
271
168
|
if (this.token) {
|
|
272
|
-
this.socket = new WebSocket
|
|
169
|
+
this.socket = new WebSocket(url.toString());
|
|
273
170
|
}
|
|
274
171
|
else {
|
|
275
|
-
this.socket = new WebSocket
|
|
172
|
+
this.socket = new WebSocket(url.toString(), {
|
|
276
173
|
headers: { Authorization: this.apiKey },
|
|
277
174
|
});
|
|
278
175
|
}
|
|
279
176
|
this.socket.onclose = ({ code, reason }) => {
|
|
280
|
-
var _a, _b;
|
|
281
177
|
if (!reason) {
|
|
282
178
|
if (code in RealtimeErrorType) {
|
|
283
179
|
reason = RealtimeErrorMessages[code];
|
|
284
180
|
}
|
|
285
181
|
}
|
|
286
|
-
|
|
182
|
+
this.listeners.close?.(code, reason);
|
|
287
183
|
};
|
|
288
184
|
this.socket.onerror = (event) => {
|
|
289
|
-
var _a, _b, _c, _d;
|
|
290
185
|
if (event.error)
|
|
291
|
-
|
|
186
|
+
this.listeners.error?.(event.error);
|
|
292
187
|
else
|
|
293
|
-
|
|
188
|
+
this.listeners.error?.(new Error(event.message));
|
|
294
189
|
};
|
|
295
190
|
this.socket.onmessage = ({ data }) => {
|
|
296
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
297
191
|
const message = JSON.parse(data.toString());
|
|
298
192
|
if ("error" in message) {
|
|
299
|
-
|
|
193
|
+
this.listeners.error?.(new RealtimeError(message.error));
|
|
300
194
|
return;
|
|
301
195
|
}
|
|
302
196
|
switch (message.message_type) {
|
|
@@ -306,25 +200,25 @@ class RealtimeService {
|
|
|
306
200
|
expiresAt: new Date(message.expires_at),
|
|
307
201
|
};
|
|
308
202
|
resolve(openObject);
|
|
309
|
-
|
|
203
|
+
this.listeners.open?.(openObject);
|
|
310
204
|
break;
|
|
311
205
|
}
|
|
312
206
|
case "PartialTranscript": {
|
|
313
207
|
// message.created is actually a string when coming from the socket
|
|
314
208
|
message.created = new Date(message.created);
|
|
315
|
-
|
|
316
|
-
|
|
209
|
+
this.listeners.transcript?.(message);
|
|
210
|
+
this.listeners["transcript.partial"]?.(message);
|
|
317
211
|
break;
|
|
318
212
|
}
|
|
319
213
|
case "FinalTranscript": {
|
|
320
214
|
// message.created is actually a string when coming from the socket
|
|
321
215
|
message.created = new Date(message.created);
|
|
322
|
-
|
|
323
|
-
|
|
216
|
+
this.listeners.transcript?.(message);
|
|
217
|
+
this.listeners["transcript.final"]?.(message);
|
|
324
218
|
break;
|
|
325
219
|
}
|
|
326
220
|
case "SessionTerminated": {
|
|
327
|
-
|
|
221
|
+
this.sessionTerminatedResolve?.();
|
|
328
222
|
break;
|
|
329
223
|
}
|
|
330
224
|
}
|
|
@@ -332,7 +226,7 @@ class RealtimeService {
|
|
|
332
226
|
});
|
|
333
227
|
}
|
|
334
228
|
sendAudio(audio) {
|
|
335
|
-
if (!this.socket || this.socket.readyState !== WebSocket
|
|
229
|
+
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
336
230
|
throw new Error("Socket is not open for communication");
|
|
337
231
|
}
|
|
338
232
|
let audioData;
|
|
@@ -356,29 +250,27 @@ class RealtimeService {
|
|
|
356
250
|
},
|
|
357
251
|
});
|
|
358
252
|
}
|
|
359
|
-
close(waitForSessionTermination = true) {
|
|
360
|
-
|
|
361
|
-
if (this.socket) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
this.socket.send(terminateSessionMessage);
|
|
373
|
-
}
|
|
253
|
+
async close(waitForSessionTermination = true) {
|
|
254
|
+
if (this.socket) {
|
|
255
|
+
if (this.socket.readyState === WebSocket.OPEN) {
|
|
256
|
+
const terminateSessionMessage = `{"terminate_session": true}`;
|
|
257
|
+
if (waitForSessionTermination) {
|
|
258
|
+
const sessionTerminatedPromise = new Promise((resolve) => {
|
|
259
|
+
this.sessionTerminatedResolve = resolve;
|
|
260
|
+
});
|
|
261
|
+
this.socket.send(terminateSessionMessage);
|
|
262
|
+
await sessionTerminatedPromise;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
this.socket.send(terminateSessionMessage);
|
|
374
266
|
}
|
|
375
|
-
if ("removeAllListeners" in this.socket)
|
|
376
|
-
this.socket.removeAllListeners();
|
|
377
|
-
this.socket.close();
|
|
378
267
|
}
|
|
379
|
-
this.
|
|
380
|
-
|
|
381
|
-
|
|
268
|
+
if ("removeAllListeners" in this.socket)
|
|
269
|
+
this.socket.removeAllListeners();
|
|
270
|
+
this.socket.close();
|
|
271
|
+
}
|
|
272
|
+
this.listeners = {};
|
|
273
|
+
this.socket = undefined;
|
|
382
274
|
}
|
|
383
275
|
}
|
|
384
276
|
|
|
@@ -395,14 +287,12 @@ class RealtimeServiceFactory extends BaseService {
|
|
|
395
287
|
}
|
|
396
288
|
return new RealtimeService(params);
|
|
397
289
|
}
|
|
398
|
-
createTemporaryToken(params) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
body: JSON.stringify(params),
|
|
403
|
-
});
|
|
404
|
-
return data.token;
|
|
290
|
+
async createTemporaryToken(params) {
|
|
291
|
+
const data = await this.fetchJson("/v2/realtime/token", {
|
|
292
|
+
method: "POST",
|
|
293
|
+
body: JSON.stringify(params),
|
|
405
294
|
});
|
|
295
|
+
return data.token;
|
|
406
296
|
}
|
|
407
297
|
}
|
|
408
298
|
|
|
@@ -417,42 +307,38 @@ class TranscriptService extends BaseService {
|
|
|
417
307
|
* @param options The options to transcribe an audio file.
|
|
418
308
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
419
309
|
*/
|
|
420
|
-
transcribe(params, options) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
return yield this.waitUntilReady(transcript.id, options);
|
|
424
|
-
});
|
|
310
|
+
async transcribe(params, options) {
|
|
311
|
+
const transcript = await this.submit(params);
|
|
312
|
+
return await this.waitUntilReady(transcript.id, options);
|
|
425
313
|
}
|
|
426
314
|
/**
|
|
427
315
|
* Submits a transcription job for an audio file. This will not wait until the transcript status is "completed" or "error".
|
|
428
316
|
* @param params The parameters to start the transcription of an audio file.
|
|
429
317
|
* @returns A promise that resolves to the queued transcript.
|
|
430
318
|
*/
|
|
431
|
-
submit(params) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
audioUrl = yield this.files.upload(path);
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
// audio is not a local path, assume it's a URL
|
|
443
|
-
audioUrl = audio;
|
|
444
|
-
}
|
|
319
|
+
async submit(params) {
|
|
320
|
+
const { audio, ...createParams } = params;
|
|
321
|
+
let audioUrl;
|
|
322
|
+
if (typeof audio === "string") {
|
|
323
|
+
const path = getPath(audio);
|
|
324
|
+
if (path !== null) {
|
|
325
|
+
// audio is local path, upload local file
|
|
326
|
+
audioUrl = await this.files.upload(path);
|
|
445
327
|
}
|
|
446
328
|
else {
|
|
447
|
-
// audio is
|
|
448
|
-
audioUrl =
|
|
329
|
+
// audio is not a local path, assume it's a URL
|
|
330
|
+
audioUrl = audio;
|
|
449
331
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
// audio is of uploadable type
|
|
335
|
+
audioUrl = await this.files.upload(audio);
|
|
336
|
+
}
|
|
337
|
+
const data = await this.fetchJson("/v2/transcript", {
|
|
338
|
+
method: "POST",
|
|
339
|
+
body: JSON.stringify({ ...createParams, audio_url: audioUrl }),
|
|
455
340
|
});
|
|
341
|
+
return data;
|
|
456
342
|
}
|
|
457
343
|
/**
|
|
458
344
|
* Create a transcript.
|
|
@@ -461,23 +347,20 @@ class TranscriptService extends BaseService {
|
|
|
461
347
|
* @returns A promise that resolves to the transcript.
|
|
462
348
|
* @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
|
|
463
349
|
*/
|
|
464
|
-
create(params, options) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
method: "POST",
|
|
474
|
-
body: JSON.stringify(params),
|
|
475
|
-
});
|
|
476
|
-
if ((_a = options === null || options === void 0 ? void 0 : options.poll) !== null && _a !== void 0 ? _a : true) {
|
|
477
|
-
return yield this.waitUntilReady(data.id, options);
|
|
478
|
-
}
|
|
479
|
-
return data;
|
|
350
|
+
async create(params, options) {
|
|
351
|
+
const path = getPath(params.audio_url);
|
|
352
|
+
if (path !== null) {
|
|
353
|
+
const uploadUrl = await this.files.upload(path);
|
|
354
|
+
params.audio_url = uploadUrl;
|
|
355
|
+
}
|
|
356
|
+
const data = await this.fetchJson("/v2/transcript", {
|
|
357
|
+
method: "POST",
|
|
358
|
+
body: JSON.stringify(params),
|
|
480
359
|
});
|
|
360
|
+
if (options?.poll ?? true) {
|
|
361
|
+
return await this.waitUntilReady(data.id, options);
|
|
362
|
+
}
|
|
363
|
+
return data;
|
|
481
364
|
}
|
|
482
365
|
/**
|
|
483
366
|
* Wait until the transcript ready, either the status is "completed" or "error".
|
|
@@ -485,27 +368,24 @@ class TranscriptService extends BaseService {
|
|
|
485
368
|
* @param options The options to wait until the transcript is ready.
|
|
486
369
|
* @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
|
|
487
370
|
*/
|
|
488
|
-
waitUntilReady(transcriptId, options) {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
if (transcript.status === "completed" || transcript.status === "error") {
|
|
498
|
-
return transcript;
|
|
499
|
-
}
|
|
500
|
-
else if (pollingTimeout > 0 &&
|
|
501
|
-
Date.now() - startTime > pollingTimeout) {
|
|
502
|
-
throw new Error("Polling timeout");
|
|
503
|
-
}
|
|
504
|
-
else {
|
|
505
|
-
yield new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
506
|
-
}
|
|
371
|
+
async waitUntilReady(transcriptId, options) {
|
|
372
|
+
const pollingInterval = options?.pollingInterval ?? 3000;
|
|
373
|
+
const pollingTimeout = options?.pollingTimeout ?? -1;
|
|
374
|
+
const startTime = Date.now();
|
|
375
|
+
// eslint-disable-next-line no-constant-condition
|
|
376
|
+
while (true) {
|
|
377
|
+
const transcript = await this.get(transcriptId);
|
|
378
|
+
if (transcript.status === "completed" || transcript.status === "error") {
|
|
379
|
+
return transcript;
|
|
507
380
|
}
|
|
508
|
-
|
|
381
|
+
else if (pollingTimeout > 0 &&
|
|
382
|
+
Date.now() - startTime > pollingTimeout) {
|
|
383
|
+
throw new Error("Polling timeout");
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
387
|
+
}
|
|
388
|
+
}
|
|
509
389
|
}
|
|
510
390
|
/**
|
|
511
391
|
* Retrieve a transcript.
|
|
@@ -519,30 +399,25 @@ class TranscriptService extends BaseService {
|
|
|
519
399
|
* Retrieves a page of transcript listings.
|
|
520
400
|
* @param parameters The parameters to filter the transcript list by, or the URL to retrieve the transcript list from.
|
|
521
401
|
*/
|
|
522
|
-
list(parameters) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
for (const transcriptListItem of data.transcripts) {
|
|
539
|
-
transcriptListItem.created = new Date(transcriptListItem.created);
|
|
540
|
-
if (transcriptListItem.completed) {
|
|
541
|
-
transcriptListItem.completed = new Date(transcriptListItem.completed);
|
|
542
|
-
}
|
|
402
|
+
async list(parameters) {
|
|
403
|
+
let url = "/v2/transcript";
|
|
404
|
+
if (typeof parameters === "string") {
|
|
405
|
+
url = parameters;
|
|
406
|
+
}
|
|
407
|
+
else if (parameters) {
|
|
408
|
+
url = `${url}?${new URLSearchParams(Object.keys(parameters).map((key) => [
|
|
409
|
+
key,
|
|
410
|
+
parameters[key]?.toString() || "",
|
|
411
|
+
]))}`;
|
|
412
|
+
}
|
|
413
|
+
const data = await this.fetchJson(url);
|
|
414
|
+
for (const transcriptListItem of data.transcripts) {
|
|
415
|
+
transcriptListItem.created = new Date(transcriptListItem.created);
|
|
416
|
+
if (transcriptListItem.completed) {
|
|
417
|
+
transcriptListItem.completed = new Date(transcriptListItem.completed);
|
|
543
418
|
}
|
|
544
|
-
|
|
545
|
-
|
|
419
|
+
}
|
|
420
|
+
return data;
|
|
546
421
|
}
|
|
547
422
|
/**
|
|
548
423
|
* Delete a transcript
|
|
@@ -586,17 +461,15 @@ class TranscriptService extends BaseService {
|
|
|
586
461
|
* @param chars_per_caption The maximum number of characters per caption.
|
|
587
462
|
* @return A promise that resolves to the subtitles text.
|
|
588
463
|
*/
|
|
589
|
-
subtitles(id, format = "srt", chars_per_caption) {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
return yield response.text();
|
|
599
|
-
});
|
|
464
|
+
async subtitles(id, format = "srt", chars_per_caption) {
|
|
465
|
+
let url = `/v2/transcript/${id}/${format}`;
|
|
466
|
+
if (chars_per_caption) {
|
|
467
|
+
const params = new URLSearchParams();
|
|
468
|
+
params.set("chars_per_caption", chars_per_caption.toString());
|
|
469
|
+
url += `?${params.toString()}`;
|
|
470
|
+
}
|
|
471
|
+
const response = await this.fetch(url);
|
|
472
|
+
return await response.text();
|
|
600
473
|
}
|
|
601
474
|
/**
|
|
602
475
|
* Retrieve redactions of a transcript.
|
|
@@ -616,19 +489,12 @@ function getPath(path) {
|
|
|
616
489
|
else
|
|
617
490
|
return null;
|
|
618
491
|
}
|
|
619
|
-
catch
|
|
492
|
+
catch {
|
|
620
493
|
return path;
|
|
621
494
|
}
|
|
622
495
|
}
|
|
623
496
|
|
|
624
|
-
|
|
625
|
-
throw new Error("Function is not supported in this environment.");
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
const createReadStream = throwError;
|
|
629
|
-
var fs = {
|
|
630
|
-
createReadStream,
|
|
631
|
-
};
|
|
497
|
+
const readFile = async (path) => Bun.file(path).stream();
|
|
632
498
|
|
|
633
499
|
class FileService extends BaseService {
|
|
634
500
|
/**
|
|
@@ -636,23 +502,21 @@ class FileService extends BaseService {
|
|
|
636
502
|
* @param input The local file path to upload, or a stream or buffer of the file to upload.
|
|
637
503
|
* @return A promise that resolves to the uploaded file URL.
|
|
638
504
|
*/
|
|
639
|
-
upload(input) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
duplex: "half",
|
|
653
|
-
});
|
|
654
|
-
return data.upload_url;
|
|
505
|
+
async upload(input) {
|
|
506
|
+
let fileData;
|
|
507
|
+
if (typeof input === "string")
|
|
508
|
+
fileData = await readFile(input);
|
|
509
|
+
else
|
|
510
|
+
fileData = input;
|
|
511
|
+
const data = await this.fetchJson("/v2/upload", {
|
|
512
|
+
method: "POST",
|
|
513
|
+
body: fileData,
|
|
514
|
+
headers: {
|
|
515
|
+
"Content-Type": "application/octet-stream",
|
|
516
|
+
},
|
|
517
|
+
duplex: "half",
|
|
655
518
|
});
|
|
519
|
+
return data.upload_url;
|
|
656
520
|
}
|
|
657
521
|
}
|
|
658
522
|
|