assemblyai 4.0.0-beta.1 → 4.0.0-beta.3

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.
@@ -1,50 +1,4 @@
1
- import { WritableStream } from '@swimburger/isomorphic-streams';
2
- import WebSocket from 'isomorphic-ws';
3
- import fs from 'fs';
4
-
5
- /******************************************************************************
6
- Copyright (c) Microsoft Corporation.
7
-
8
- Permission to use, copy, modify, and/or distribute this software for any
9
- purpose with or without fee is hereby granted.
10
-
11
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
- PERFORMANCE OF THIS SOFTWARE.
18
- ***************************************************************************** */
19
- /* global Reflect, Promise, SuppressedError, Symbol */
20
-
21
-
22
- function __rest(s, e) {
23
- var t = {};
24
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
25
- t[p] = s[p];
26
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
27
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
28
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
29
- t[p[i]] = s[p[i]];
30
- }
31
- return t;
32
- }
33
-
34
- function __awaiter(thisArg, _arguments, P, generator) {
35
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
36
- return new (P || (P = Promise))(function (resolve, reject) {
37
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
38
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
39
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
40
- step((generator = generator.apply(thisArg, _arguments || [])).next());
41
- });
42
- }
43
-
44
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
45
- var e = new Error(message);
46
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
47
- };
1
+ import WebSocket from '#ws';
48
2
 
49
3
  /**
50
4
  * Base class for services that communicate with the API.
@@ -57,39 +11,38 @@ class BaseService {
57
11
  constructor(params) {
58
12
  this.params = params;
59
13
  }
60
- fetch(input, init) {
61
- var _a;
62
- return __awaiter(this, void 0, void 0, function* () {
63
- init = init !== null && init !== void 0 ? init : {};
64
- init.headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
65
- init.headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
66
- if (!input.startsWith("http"))
67
- input = this.params.baseUrl + input;
68
- const response = yield fetch(input, init);
69
- if (response.status >= 400) {
70
- let json;
71
- const text = yield response.text();
72
- if (text) {
73
- try {
74
- json = JSON.parse(text);
75
- }
76
- catch (_b) {
77
- /* empty */
78
- }
79
- if (json === null || json === void 0 ? void 0 : json.error)
80
- throw new Error(json.error);
81
- throw new Error(text);
14
+ async fetch(input, init) {
15
+ init = init ?? {};
16
+ init.headers = init.headers ?? {};
17
+ init.headers = {
18
+ Authorization: this.params.apiKey,
19
+ "Content-Type": "application/json",
20
+ ...init.headers,
21
+ };
22
+ if (!input.startsWith("http"))
23
+ input = this.params.baseUrl + input;
24
+ const response = await fetch(input, init);
25
+ if (response.status >= 400) {
26
+ let json;
27
+ const text = await response.text();
28
+ if (text) {
29
+ try {
30
+ json = JSON.parse(text);
31
+ }
32
+ catch {
33
+ /* empty */
82
34
  }
83
- throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
35
+ if (json?.error)
36
+ throw new Error(json.error);
37
+ throw new Error(text);
84
38
  }
85
- return response;
86
- });
39
+ throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
40
+ }
41
+ return response;
87
42
  }
88
- fetchJson(input, init) {
89
- return __awaiter(this, void 0, void 0, function* () {
90
- const response = yield this.fetch(input, init);
91
- return response.json();
92
- });
43
+ async fetchJson(input, init) {
44
+ const response = await this.fetch(input, init);
45
+ return response.json();
93
46
  }
94
47
  }
95
48
 
@@ -129,6 +82,12 @@ class LemurService extends BaseService {
129
82
  }
130
83
  }
131
84
 
85
+ const { WritableStream } = typeof window !== "undefined"
86
+ ? window
87
+ : typeof global !== "undefined"
88
+ ? global
89
+ : globalThis;
90
+
132
91
  var RealtimeErrorType;
133
92
  (function (RealtimeErrorType) {
134
93
  RealtimeErrorType[RealtimeErrorType["BadSampleRate"] = 4000] = "BadSampleRate";
@@ -173,10 +132,9 @@ class RealtimeError extends Error {
173
132
  const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
174
133
  class RealtimeService {
175
134
  constructor(params) {
176
- var _a, _b;
177
135
  this.listeners = {};
178
- this.realtimeUrl = (_a = params.realtimeUrl) !== null && _a !== void 0 ? _a : defaultRealtimeUrl;
179
- this.sampleRate = (_b = params.sampleRate) !== null && _b !== void 0 ? _b : 16000;
136
+ this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
137
+ this.sampleRate = params.sampleRate ?? 16000;
180
138
  this.wordBoost = params.wordBoost;
181
139
  if ("apiKey" in params && params.apiKey)
182
140
  this.apiKey = params.apiKey;
@@ -221,26 +179,23 @@ class RealtimeService {
221
179
  });
222
180
  }
223
181
  this.socket.onclose = ({ code, reason }) => {
224
- var _a, _b;
225
182
  if (!reason) {
226
183
  if (code in RealtimeErrorType) {
227
184
  reason = RealtimeErrorMessages[code];
228
185
  }
229
186
  }
230
- (_b = (_a = this.listeners).close) === null || _b === void 0 ? void 0 : _b.call(_a, code, reason);
187
+ this.listeners.close?.(code, reason);
231
188
  };
232
189
  this.socket.onerror = (event) => {
233
- var _a, _b, _c, _d;
234
190
  if (event.error)
235
- (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, event.error);
191
+ this.listeners.error?.(event.error);
236
192
  else
237
- (_d = (_c = this.listeners).error) === null || _d === void 0 ? void 0 : _d.call(_c, new Error(event.message));
193
+ this.listeners.error?.(new Error(event.message));
238
194
  };
239
195
  this.socket.onmessage = ({ data }) => {
240
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
241
196
  const message = JSON.parse(data.toString());
242
197
  if ("error" in message) {
243
- (_b = (_a = this.listeners).error) === null || _b === void 0 ? void 0 : _b.call(_a, new RealtimeError(message.error));
198
+ this.listeners.error?.(new RealtimeError(message.error));
244
199
  return;
245
200
  }
246
201
  switch (message.message_type) {
@@ -250,25 +205,25 @@ class RealtimeService {
250
205
  expiresAt: new Date(message.expires_at),
251
206
  };
252
207
  resolve(openObject);
253
- (_d = (_c = this.listeners).open) === null || _d === void 0 ? void 0 : _d.call(_c, openObject);
208
+ this.listeners.open?.(openObject);
254
209
  break;
255
210
  }
256
211
  case "PartialTranscript": {
257
212
  // message.created is actually a string when coming from the socket
258
213
  message.created = new Date(message.created);
259
- (_f = (_e = this.listeners).transcript) === null || _f === void 0 ? void 0 : _f.call(_e, message);
260
- (_h = (_g = this.listeners)["transcript.partial"]) === null || _h === void 0 ? void 0 : _h.call(_g, message);
214
+ this.listeners.transcript?.(message);
215
+ this.listeners["transcript.partial"]?.(message);
261
216
  break;
262
217
  }
263
218
  case "FinalTranscript": {
264
219
  // message.created is actually a string when coming from the socket
265
220
  message.created = new Date(message.created);
266
- (_k = (_j = this.listeners).transcript) === null || _k === void 0 ? void 0 : _k.call(_j, message);
267
- (_m = (_l = this.listeners)["transcript.final"]) === null || _m === void 0 ? void 0 : _m.call(_l, message);
221
+ this.listeners.transcript?.(message);
222
+ this.listeners["transcript.final"]?.(message);
268
223
  break;
269
224
  }
270
225
  case "SessionTerminated": {
271
- (_o = this.sessionTerminatedResolve) === null || _o === void 0 ? void 0 : _o.call(this);
226
+ this.sessionTerminatedResolve?.();
272
227
  break;
273
228
  }
274
229
  }
@@ -300,29 +255,27 @@ class RealtimeService {
300
255
  },
301
256
  });
302
257
  }
303
- close(waitForSessionTermination = true) {
304
- return __awaiter(this, void 0, void 0, function* () {
305
- if (this.socket) {
306
- if (this.socket.readyState === WebSocket.OPEN) {
307
- const terminateSessionMessage = `{"terminate_session": true}`;
308
- if (waitForSessionTermination) {
309
- const sessionTerminatedPromise = new Promise((resolve) => {
310
- this.sessionTerminatedResolve = resolve;
311
- });
312
- this.socket.send(terminateSessionMessage);
313
- yield sessionTerminatedPromise;
314
- }
315
- else {
316
- this.socket.send(terminateSessionMessage);
317
- }
258
+ async close(waitForSessionTermination = true) {
259
+ if (this.socket) {
260
+ if (this.socket.readyState === WebSocket.OPEN) {
261
+ const terminateSessionMessage = `{"terminate_session": true}`;
262
+ if (waitForSessionTermination) {
263
+ const sessionTerminatedPromise = new Promise((resolve) => {
264
+ this.sessionTerminatedResolve = resolve;
265
+ });
266
+ this.socket.send(terminateSessionMessage);
267
+ await sessionTerminatedPromise;
268
+ }
269
+ else {
270
+ this.socket.send(terminateSessionMessage);
318
271
  }
319
- if ("removeAllListeners" in this.socket)
320
- this.socket.removeAllListeners();
321
- this.socket.close();
322
272
  }
323
- this.listeners = {};
324
- this.socket = undefined;
325
- });
273
+ if ("removeAllListeners" in this.socket)
274
+ this.socket.removeAllListeners();
275
+ this.socket.close();
276
+ }
277
+ this.listeners = {};
278
+ this.socket = undefined;
326
279
  }
327
280
  }
328
281
 
@@ -339,14 +292,12 @@ class RealtimeServiceFactory extends BaseService {
339
292
  }
340
293
  return new RealtimeService(params);
341
294
  }
342
- createTemporaryToken(params) {
343
- return __awaiter(this, void 0, void 0, function* () {
344
- const data = yield this.fetchJson("/v2/realtime/token", {
345
- method: "POST",
346
- body: JSON.stringify(params),
347
- });
348
- return data.token;
295
+ async createTemporaryToken(params) {
296
+ const data = await this.fetchJson("/v2/realtime/token", {
297
+ method: "POST",
298
+ body: JSON.stringify(params),
349
299
  });
300
+ return data.token;
350
301
  }
351
302
  }
352
303
 
@@ -361,42 +312,38 @@ class TranscriptService extends BaseService {
361
312
  * @param options The options to transcribe an audio file.
362
313
  * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
363
314
  */
364
- transcribe(params, options) {
365
- return __awaiter(this, void 0, void 0, function* () {
366
- const transcript = yield this.submit(params);
367
- return yield this.waitUntilReady(transcript.id, options);
368
- });
315
+ async transcribe(params, options) {
316
+ const transcript = await this.submit(params);
317
+ return await this.waitUntilReady(transcript.id, options);
369
318
  }
370
319
  /**
371
320
  * Submits a transcription job for an audio file. This will not wait until the transcript status is "completed" or "error".
372
321
  * @param params The parameters to start the transcription of an audio file.
373
322
  * @returns A promise that resolves to the queued transcript.
374
323
  */
375
- submit(params) {
376
- return __awaiter(this, void 0, void 0, function* () {
377
- const { audio } = params, createParams = __rest(params, ["audio"]);
378
- let audioUrl;
379
- if (typeof audio === "string") {
380
- const path = getPath(audio);
381
- if (path !== null) {
382
- // audio is local path, upload local file
383
- audioUrl = yield this.files.upload(path);
384
- }
385
- else {
386
- // audio is not a local path, assume it's a URL
387
- audioUrl = audio;
388
- }
324
+ async submit(params) {
325
+ const { audio, ...createParams } = params;
326
+ let audioUrl;
327
+ if (typeof audio === "string") {
328
+ const path = getPath(audio);
329
+ if (path !== null) {
330
+ // audio is local path, upload local file
331
+ audioUrl = await this.files.upload(path);
389
332
  }
390
333
  else {
391
- // audio is of uploadable type
392
- audioUrl = yield this.files.upload(audio);
334
+ // audio is not a local path, assume it's a URL
335
+ audioUrl = audio;
393
336
  }
394
- const data = yield this.fetchJson("/v2/transcript", {
395
- method: "POST",
396
- body: JSON.stringify(Object.assign(Object.assign({}, createParams), { audio_url: audioUrl })),
397
- });
398
- return data;
337
+ }
338
+ else {
339
+ // audio is of uploadable type
340
+ audioUrl = await this.files.upload(audio);
341
+ }
342
+ const data = await this.fetchJson("/v2/transcript", {
343
+ method: "POST",
344
+ body: JSON.stringify({ ...createParams, audio_url: audioUrl }),
399
345
  });
346
+ return data;
400
347
  }
401
348
  /**
402
349
  * Create a transcript.
@@ -405,23 +352,20 @@ class TranscriptService extends BaseService {
405
352
  * @returns A promise that resolves to the transcript.
406
353
  * @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
407
354
  */
408
- create(params, options) {
409
- var _a;
410
- return __awaiter(this, void 0, void 0, function* () {
411
- const path = getPath(params.audio_url);
412
- if (path !== null) {
413
- const uploadUrl = yield this.files.upload(path);
414
- params.audio_url = uploadUrl;
415
- }
416
- const data = yield this.fetchJson("/v2/transcript", {
417
- method: "POST",
418
- body: JSON.stringify(params),
419
- });
420
- if ((_a = options === null || options === void 0 ? void 0 : options.poll) !== null && _a !== void 0 ? _a : true) {
421
- return yield this.waitUntilReady(data.id, options);
422
- }
423
- return data;
355
+ async create(params, options) {
356
+ const path = getPath(params.audio_url);
357
+ if (path !== null) {
358
+ const uploadUrl = await this.files.upload(path);
359
+ params.audio_url = uploadUrl;
360
+ }
361
+ const data = await this.fetchJson("/v2/transcript", {
362
+ method: "POST",
363
+ body: JSON.stringify(params),
424
364
  });
365
+ if (options?.poll ?? true) {
366
+ return await this.waitUntilReady(data.id, options);
367
+ }
368
+ return data;
425
369
  }
426
370
  /**
427
371
  * Wait until the transcript ready, either the status is "completed" or "error".
@@ -429,27 +373,24 @@ class TranscriptService extends BaseService {
429
373
  * @param options The options to wait until the transcript is ready.
430
374
  * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
431
375
  */
432
- waitUntilReady(transcriptId, options) {
433
- var _a, _b;
434
- return __awaiter(this, void 0, void 0, function* () {
435
- const pollingInterval = (_a = options === null || options === void 0 ? void 0 : options.pollingInterval) !== null && _a !== void 0 ? _a : 3000;
436
- const pollingTimeout = (_b = options === null || options === void 0 ? void 0 : options.pollingTimeout) !== null && _b !== void 0 ? _b : -1;
437
- const startTime = Date.now();
438
- // eslint-disable-next-line no-constant-condition
439
- while (true) {
440
- const transcript = yield this.get(transcriptId);
441
- if (transcript.status === "completed" || transcript.status === "error") {
442
- return transcript;
443
- }
444
- else if (pollingTimeout > 0 &&
445
- Date.now() - startTime > pollingTimeout) {
446
- throw new Error("Polling timeout");
447
- }
448
- else {
449
- yield new Promise((resolve) => setTimeout(resolve, pollingInterval));
450
- }
376
+ async waitUntilReady(transcriptId, options) {
377
+ const pollingInterval = options?.pollingInterval ?? 3000;
378
+ const pollingTimeout = options?.pollingTimeout ?? -1;
379
+ const startTime = Date.now();
380
+ // eslint-disable-next-line no-constant-condition
381
+ while (true) {
382
+ const transcript = await this.get(transcriptId);
383
+ if (transcript.status === "completed" || transcript.status === "error") {
384
+ return transcript;
451
385
  }
452
- });
386
+ else if (pollingTimeout > 0 &&
387
+ Date.now() - startTime > pollingTimeout) {
388
+ throw new Error("Polling timeout");
389
+ }
390
+ else {
391
+ await new Promise((resolve) => setTimeout(resolve, pollingInterval));
392
+ }
393
+ }
453
394
  }
454
395
  /**
455
396
  * Retrieve a transcript.
@@ -463,30 +404,25 @@ class TranscriptService extends BaseService {
463
404
  * Retrieves a page of transcript listings.
464
405
  * @param parameters The parameters to filter the transcript list by, or the URL to retrieve the transcript list from.
465
406
  */
466
- list(parameters) {
467
- return __awaiter(this, void 0, void 0, function* () {
468
- let url = "/v2/transcript";
469
- if (typeof parameters === "string") {
470
- url = parameters;
471
- }
472
- else if (parameters) {
473
- url = `${url}?${new URLSearchParams(Object.keys(parameters).map((key) => {
474
- var _a;
475
- return [
476
- key,
477
- ((_a = parameters[key]) === null || _a === void 0 ? void 0 : _a.toString()) || "",
478
- ];
479
- }))}`;
480
- }
481
- const data = yield this.fetchJson(url);
482
- for (const transcriptListItem of data.transcripts) {
483
- transcriptListItem.created = new Date(transcriptListItem.created);
484
- if (transcriptListItem.completed) {
485
- transcriptListItem.completed = new Date(transcriptListItem.completed);
486
- }
407
+ async list(parameters) {
408
+ let url = "/v2/transcript";
409
+ if (typeof parameters === "string") {
410
+ url = parameters;
411
+ }
412
+ else if (parameters) {
413
+ url = `${url}?${new URLSearchParams(Object.keys(parameters).map((key) => [
414
+ key,
415
+ parameters[key]?.toString() || "",
416
+ ]))}`;
417
+ }
418
+ const data = await this.fetchJson(url);
419
+ for (const transcriptListItem of data.transcripts) {
420
+ transcriptListItem.created = new Date(transcriptListItem.created);
421
+ if (transcriptListItem.completed) {
422
+ transcriptListItem.completed = new Date(transcriptListItem.completed);
487
423
  }
488
- return data;
489
- });
424
+ }
425
+ return data;
490
426
  }
491
427
  /**
492
428
  * Delete a transcript
@@ -530,17 +466,15 @@ class TranscriptService extends BaseService {
530
466
  * @param chars_per_caption The maximum number of characters per caption.
531
467
  * @return A promise that resolves to the subtitles text.
532
468
  */
533
- subtitles(id, format = "srt", chars_per_caption) {
534
- return __awaiter(this, void 0, void 0, function* () {
535
- let url = `/v2/transcript/${id}/${format}`;
536
- if (chars_per_caption) {
537
- const params = new URLSearchParams();
538
- params.set("chars_per_caption", chars_per_caption.toString());
539
- url += `?${params.toString()}`;
540
- }
541
- const response = yield this.fetch(url);
542
- return yield response.text();
543
- });
469
+ async subtitles(id, format = "srt", chars_per_caption) {
470
+ let url = `/v2/transcript/${id}/${format}`;
471
+ if (chars_per_caption) {
472
+ const params = new URLSearchParams();
473
+ params.set("chars_per_caption", chars_per_caption.toString());
474
+ url += `?${params.toString()}`;
475
+ }
476
+ const response = await this.fetch(url);
477
+ return await response.text();
544
478
  }
545
479
  /**
546
480
  * Retrieve redactions of a transcript.
@@ -560,34 +494,34 @@ function getPath(path) {
560
494
  else
561
495
  return null;
562
496
  }
563
- catch (_a) {
497
+ catch {
564
498
  return path;
565
499
  }
566
500
  }
567
501
 
502
+ const readFile = async (path) => Bun.file(path).stream();
503
+
568
504
  class FileService extends BaseService {
569
505
  /**
570
506
  * Upload a local file to AssemblyAI.
571
507
  * @param input The local file path to upload, or a stream or buffer of the file to upload.
572
508
  * @return A promise that resolves to the uploaded file URL.
573
509
  */
574
- upload(input) {
575
- return __awaiter(this, void 0, void 0, function* () {
576
- let fileData;
577
- if (typeof input === "string")
578
- fileData = fs.createReadStream(input);
579
- else
580
- fileData = input;
581
- const data = yield this.fetchJson("/v2/upload", {
582
- method: "POST",
583
- body: fileData,
584
- headers: {
585
- "Content-Type": "application/octet-stream",
586
- },
587
- duplex: "half",
588
- });
589
- return data.upload_url;
510
+ async upload(input) {
511
+ let fileData;
512
+ if (typeof input === "string")
513
+ fileData = await readFile(input);
514
+ else
515
+ fileData = input;
516
+ const data = await this.fetchJson("/v2/upload", {
517
+ method: "POST",
518
+ body: fileData,
519
+ headers: {
520
+ "Content-Type": "application/octet-stream",
521
+ },
522
+ duplex: "half",
590
523
  });
524
+ return data.upload_url;
591
525
  }
592
526
  }
593
527