assemblyai 4.5.0-beta.0 → 4.5.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +53 -9
  3. package/dist/assemblyai.streaming.umd.js +288 -0
  4. package/dist/assemblyai.streaming.umd.min.js +1 -0
  5. package/dist/assemblyai.umd.js +131 -12
  6. package/dist/assemblyai.umd.min.js +1 -1
  7. package/dist/browser.mjs +125 -11
  8. package/dist/bun.mjs +125 -11
  9. package/dist/deno.mjs +125 -11
  10. package/dist/exports/index.d.ts +2 -0
  11. package/dist/exports/streaming.d.ts +4 -0
  12. package/dist/index.cjs +131 -12
  13. package/dist/index.mjs +131 -12
  14. package/dist/node.cjs +125 -11
  15. package/dist/node.mjs +125 -11
  16. package/dist/polyfills/fetch/default.d.ts +1 -0
  17. package/dist/polyfills/fetch/workerd.d.ts +1 -0
  18. package/dist/services/base.d.ts +1 -0
  19. package/dist/services/lemur/index.d.ts +8 -1
  20. package/dist/services/transcripts/index.d.ts +16 -3
  21. package/dist/streaming.browser.mjs +239 -0
  22. package/dist/streaming.cjs +277 -0
  23. package/dist/streaming.mjs +274 -0
  24. package/dist/types/index.d.ts +7 -0
  25. package/dist/types/openapi.generated.d.ts +60 -23
  26. package/dist/types/services/index.d.ts +7 -0
  27. package/dist/types/transcripts/index.d.ts +9 -0
  28. package/dist/utils/userAgent.d.ts +2 -0
  29. package/dist/workerd.mjs +722 -0
  30. package/docs/reference-types-from-js.md +27 -0
  31. package/package.json +39 -19
  32. package/src/exports/index.ts +2 -0
  33. package/src/exports/streaming.ts +4 -0
  34. package/src/polyfills/fetch/default.ts +3 -0
  35. package/src/polyfills/fetch/workerd.ts +1 -0
  36. package/src/services/base.ts +27 -7
  37. package/src/services/files/index.ts +19 -2
  38. package/src/services/index.ts +2 -1
  39. package/src/services/lemur/index.ts +12 -0
  40. package/src/services/transcripts/index.ts +41 -4
  41. package/src/types/index.ts +9 -0
  42. package/src/types/openapi.generated.ts +198 -41
  43. package/src/types/services/index.ts +8 -0
  44. package/src/types/transcripts/index.ts +10 -0
  45. package/src/utils/path.ts +1 -0
  46. package/src/utils/userAgent.ts +51 -0
@@ -0,0 +1,27 @@
1
+ # Reference types from JavaScript
2
+
3
+ Types are automatically configured in most IDEs when you import the `assemblyai` module using `require` or `import`.
4
+ However, if you're using the _assemblyai.umd.js_ or _assemblyai.umd.min.js_ script,
5
+ you need to manually reference the types.
6
+
7
+ 1. Install the `assemblyai` module locally.
8
+ 2. Create an _assemblyai.d.ts_ file with the following content.
9
+ ```typescript
10
+ import AssemblyAIModule from "assemblyai";
11
+ declare global {
12
+ const assemblyai: typeof AssemblyAIModule;
13
+ }
14
+ ```
15
+ This will import the TypeScript types from the `assemblyai` module,
16
+ and configure them as the global `assemblyai` variable.
17
+ 3. Reference the _assemblyai.d.ts_ file at the top of your script file.
18
+
19
+ ```js
20
+ /// <reference path="assemblyai.d.ts" />
21
+ const { RealtimeTranscriber } = assemblyai;
22
+ ...
23
+ ```
24
+
25
+ Your IDE will load the types specified in the `<reference />` tag.
26
+
27
+ > [!INFO] > `/// <reference />` tags only work in script files, not script-blocks, and should be at the top of the file.
package/package.json CHANGED
@@ -1,25 +1,26 @@
1
1
  {
2
2
  "name": "assemblyai",
3
- "version": "4.5.0-beta.0",
3
+ "version": "4.5.0",
4
4
  "description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription, as well as the latest LeMUR models.",
5
5
  "engines": {
6
6
  "node": ">=18"
7
7
  },
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/index.d.ts",
10
+ "types": "./dist/exports/index.d.ts",
11
11
  "bun": {
12
- "types": "./dist/index.d.ts",
12
+ "types": "./dist/exports/index.d.ts",
13
13
  "default": "./dist/bun.mjs"
14
14
  },
15
15
  "deno": {
16
- "types": "./dist/index.d.ts",
16
+ "types": "./dist/exports/index.d.ts",
17
17
  "default": "./dist/deno.mjs"
18
18
  },
19
- "workerd": "./dist/index.mjs",
19
+ "workerd": "./dist/workerd.mjs",
20
20
  "browser": "./dist/browser.mjs",
21
+ "react-native": "./dist/browser.mjs",
21
22
  "node": {
22
- "types": "./dist/index.d.ts",
23
+ "types": "./dist/exports/index.d.ts",
23
24
  "import": "./dist/node.mjs",
24
25
  "require": "./dist/node.cjs"
25
26
  },
@@ -27,9 +28,20 @@
27
28
  "require": "./dist/index.cjs",
28
29
  "default": "./dist/index.cjs"
29
30
  },
31
+ "./streaming": {
32
+ "types": "./dist/exports/streaming.d.ts",
33
+ "browser": "./dist/streaming.browser.mjs",
34
+ "import": "./dist/streaming.mjs",
35
+ "require": "./dist/streaming.cjs",
36
+ "default": "./dist/streaming.cjs"
37
+ },
30
38
  "./package.json": "./package.json"
31
39
  },
32
40
  "imports": {
41
+ "#fetch": {
42
+ "workerd": "./src/polyfills/fetch/workerd.ts",
43
+ "default": "./src/polyfills/fetch/default.ts"
44
+ },
33
45
  "#fs": {
34
46
  "node": "./src/polyfills/fs/node.ts",
35
47
  "bun": "./src/polyfills/fs/bun.ts",
@@ -47,6 +59,8 @@
47
59
  }
48
60
  },
49
61
  "type": "commonjs",
62
+ "react-native": "./dist/browser.mjs",
63
+ "browser": "./dist/browser.mjs",
50
64
  "main": "./dist/index.cjs",
51
65
  "require": "./dist/index.cjs",
52
66
  "module": "./dist/index.mjs",
@@ -57,18 +71,22 @@
57
71
  "url": "git+https://github.com/AssemblyAI/assemblyai-node-sdk.git"
58
72
  },
59
73
  "publishConfig": {
60
- "tag": "beta",
74
+ "tag": "latest",
61
75
  "access": "public",
62
76
  "registry": "https://registry.npmjs.org/"
63
77
  },
64
78
  "scripts": {
65
79
  "build": "pnpm clean && pnpm rollup -c",
66
80
  "clean": "rimraf dist/* && rimraf temp/* && rimraf temp-docs/*",
67
- "lint": "eslint -c .eslintrc.json '{src,tests}/**/*.{js,ts}' && publint && tsc --noEmit -p tsconfig.json",
68
- "test": "pnpm run test:unit && pnpm run test:integration",
81
+ "lint": "pnpm lint:eslint && pnpm lint:tsc && pnpm lint:format && pnpm lint:publint",
82
+ "lint:eslint": "eslint -c .eslintrc.json '{src,tests}/**/*.{js,ts}'",
83
+ "lint:tsc": "tsc --noEmit -p tsconfig.json",
84
+ "lint:format": "prettier --check --no-error-on-unmatched-pattern {*,**/*}",
85
+ "lint:publint": "publint",
86
+ "test": "pnpm test:unit && pnpm test:integration",
69
87
  "test:unit": "jest --config jest.unit.config.js --testTimeout 1000",
70
88
  "test:integration": "jest --config jest.integration.config.js --testTimeout 360000",
71
- "format": "prettier '**/*' --write",
89
+ "format": "prettier --write --no-error-on-unmatched-pattern {*,**/*}",
72
90
  "generate:types": "tsx ./scripts/generate-types.ts && prettier 'src/types/*.generated.ts' --write",
73
91
  "generate:reference": "typedoc",
74
92
  "copybara:dry-run": "./copybara.sh dry_run --init-history",
@@ -97,16 +115,17 @@
97
115
  "docs"
98
116
  ],
99
117
  "devDependencies": {
100
- "@babel/preset-env": "^7.24.0",
101
- "@babel/preset-typescript": "^7.23.3",
118
+ "@babel/preset-env": "^7.24.5",
119
+ "@babel/preset-typescript": "^7.24.1",
102
120
  "@rollup/plugin-node-resolve": "^15.2.3",
121
+ "@rollup/plugin-replace": "^5.0.5",
103
122
  "@rollup/plugin-terser": "^0.4.4",
104
123
  "@rollup/plugin-typescript": "^11.1.6",
105
124
  "@types/jest": "^29.5.12",
106
- "@types/node": "^18.11.9",
125
+ "@types/node": "^18.19.32",
107
126
  "@types/websocket": "^1.0.10",
108
127
  "@types/ws": "^8.5.10",
109
- "@typescript-eslint/eslint-plugin": "^7.2.0",
128
+ "@typescript-eslint/eslint-plugin": "^7.8.0",
110
129
  "dotenv": "^16.4.5",
111
130
  "eslint": "^8.57.0",
112
131
  "eslint-plugin-tsdoc": "^0.2.17",
@@ -115,19 +134,20 @@
115
134
  "jest-fetch-mock": "^3.0.3",
116
135
  "jest-junit": "^16.0.0",
117
136
  "jest-websocket-mock": "^2.5.0",
137
+ "jsr": "^0.12.4",
118
138
  "mock-socket": "^9.3.1",
119
139
  "openapi-typescript": "^6.7.5",
120
140
  "prettier": "^3.2.5",
121
141
  "publint": "^0.2.7",
122
142
  "rimraf": "^5.0.5",
123
- "rollup": "^4.13.0",
143
+ "rollup": "^4.17.2",
124
144
  "ts-jest": "^29.1.2",
125
145
  "tslib": "^2.5.3",
126
- "typescript": "^5.4.2",
127
- "typedoc": "^0.25.12",
128
- "typedoc-plugin-extras": "^3.0.0"
146
+ "typedoc": "^0.25.13",
147
+ "typedoc-plugin-extras": "^3.0.0",
148
+ "typescript": "^5.4.5"
129
149
  },
130
150
  "dependencies": {
131
- "ws": "^8.16.0"
151
+ "ws": "^8.17.0"
132
152
  }
133
153
  }
@@ -0,0 +1,2 @@
1
+ export * from "../types";
2
+ export * from "../services";
@@ -0,0 +1,4 @@
1
+ export * from "../types/asyncapi.generated";
2
+ export * from "../types/realtime";
3
+ export * from "../types/helpers";
4
+ export * from "../services/realtime/service";
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_FETCH_INIT: Record<string, unknown> = {
2
+ cache: "no-store",
3
+ };
@@ -0,0 +1 @@
1
+ export const DEFAULT_FETCH_INIT: Record<string, unknown> = {};
@@ -1,26 +1,46 @@
1
- import { BaseServiceParams } from "..";
2
- import { Error as JsonError } from "..";
1
+ import { DEFAULT_FETCH_INIT } from "#fetch";
2
+ import { BaseServiceParams, Error as JsonError } from "..";
3
+ import { buildUserAgent } from "../utils/userAgent";
3
4
 
4
5
  /**
5
6
  * Base class for services that communicate with the API.
6
7
  */
7
8
  export abstract class BaseService {
9
+ private userAgent: string | undefined;
8
10
  /**
9
11
  * Create a new service.
10
12
  * @param params - The parameters to use for the service.
11
13
  */
12
- constructor(private params: BaseServiceParams) {}
14
+ constructor(private params: BaseServiceParams) {
15
+ if (params.userAgent === false) {
16
+ this.userAgent = undefined;
17
+ } else {
18
+ this.userAgent = buildUserAgent(params.userAgent || {});
19
+ }
20
+ }
13
21
  protected async fetch(
14
22
  input: string,
15
23
  init?: RequestInit | undefined,
16
24
  ): Promise<Response> {
17
- init = init ?? {};
18
- init.headers = init.headers ?? {};
19
- init.headers = {
25
+ init = { ...DEFAULT_FETCH_INIT, ...init };
26
+ let headers = {
20
27
  Authorization: this.params.apiKey,
21
28
  "Content-Type": "application/json",
22
- ...init.headers,
23
29
  };
30
+ if (DEFAULT_FETCH_INIT?.headers)
31
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
32
+ if (init?.headers) headers = { ...headers, ...init.headers };
33
+
34
+ if (this.userAgent) {
35
+ (headers as Record<string, string>)["User-Agent"] = this.userAgent;
36
+ // chromium browsers have a bug where the user agent can't be modified
37
+ if (typeof window !== "undefined" && "chrome" in window) {
38
+ (headers as Record<string, string>)["AssemblyAI-Agent"] =
39
+ this.userAgent;
40
+ }
41
+ }
42
+ init.headers = headers;
43
+
24
44
  if (!input.startsWith("http")) input = this.params.baseUrl + input;
25
45
 
26
46
  const response = await fetch(input, init);
@@ -10,8 +10,13 @@ export class FileService extends BaseService {
10
10
  */
11
11
  async upload(input: FileUploadParams): Promise<string> {
12
12
  let fileData: FileUploadData;
13
- if (typeof input === "string") fileData = await readFile(input);
14
- else fileData = input;
13
+ if (typeof input === "string") {
14
+ if (input.startsWith("data:")) {
15
+ fileData = dataUrlToBlob(input);
16
+ } else {
17
+ fileData = await readFile(input);
18
+ }
19
+ } else fileData = input;
15
20
 
16
21
  const data = await this.fetchJson<UploadedFile>("/v2/upload", {
17
22
  method: "POST",
@@ -24,3 +29,15 @@ export class FileService extends BaseService {
24
29
  return data.upload_url;
25
30
  }
26
31
  }
32
+
33
+ function dataUrlToBlob(dataUrl: string) {
34
+ const arr = dataUrl.split(",");
35
+ const mime = arr[0].match(/:(.*?);/)![1];
36
+ const bstr = atob(arr[1]);
37
+ let n = bstr.length;
38
+ const u8arr = new Uint8Array(n);
39
+ while (n--) {
40
+ u8arr[n] = bstr.charCodeAt(n);
41
+ }
42
+ return new Blob([u8arr], { type: mime });
43
+ }
@@ -38,8 +38,9 @@ class AssemblyAI {
38
38
  */
39
39
  constructor(params: BaseServiceParams) {
40
40
  params.baseUrl = params.baseUrl || defaultBaseUrl;
41
- if (params.baseUrl && params.baseUrl.endsWith("/"))
41
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
42
42
  params.baseUrl = params.baseUrl.slice(0, -1);
43
+ }
43
44
  this.files = new FileService(params);
44
45
  this.transcripts = new TranscriptService(params, this.files);
45
46
  this.lemur = new LemurService(params);
@@ -8,6 +8,7 @@ import {
8
8
  LemurActionItemsResponse,
9
9
  LemurTaskResponse,
10
10
  PurgeLemurRequestDataResponse,
11
+ LemurResponse,
11
12
  } from "../..";
12
13
  import { BaseService } from "../base";
13
14
 
@@ -50,6 +51,17 @@ export class LemurService extends BaseService {
50
51
  });
51
52
  }
52
53
 
54
+ /**
55
+ * Retrieve a LeMUR response that was previously generated.
56
+ * @param id - The ID of the LeMUR request you previously made. This would be found in the response of the original request.
57
+ * @returns The LeMUR response.
58
+ */
59
+ getResponse<T extends LemurResponse>(id: string): Promise<T>;
60
+ getResponse(id: string): Promise<LemurResponse>;
61
+ getResponse(id: string): Promise<LemurResponse> {
62
+ return this.fetchJson<LemurResponse>(`/lemur/v3/${id}`);
63
+ }
64
+
53
65
  /**
54
66
  * Delete the data for a previously submitted LeMUR request.
55
67
  * @param id - ID of the LeMUR request
@@ -16,6 +16,7 @@ import {
16
16
  TranscribeOptions,
17
17
  SubmitParams,
18
18
  SpeechModel,
19
+ RedactedAudioFile,
19
20
  } from "../..";
20
21
  import { FileService } from "../files";
21
22
  import { getPath } from "../../utils/path";
@@ -60,8 +61,12 @@ export class TranscriptService extends BaseService {
60
61
  // audio is local path, upload local file
61
62
  audioUrl = await this.files.upload(path);
62
63
  } else {
63
- // audio is not a local path, assume it's a URL
64
- audioUrl = audio;
64
+ if (audio.startsWith("data:")) {
65
+ audioUrl = await this.files.upload(audio);
66
+ } else {
67
+ // audio is not a local path, and not a data-URI, assume it's a normal URL
68
+ audioUrl = audio;
69
+ }
65
70
  }
66
71
  } else {
67
72
  // audio is of uploadable type
@@ -240,15 +245,47 @@ export class TranscriptService extends BaseService {
240
245
  }
241
246
 
242
247
  /**
243
- * Retrieve redactions of a transcript.
248
+ * Retrieve the redacted audio URL of a transcript.
244
249
  * @param id - The identifier of the transcript.
245
- * @returns A promise that resolves to the subtitles text.
250
+ * @returns A promise that resolves to the details of the redacted audio.
251
+ * @deprecated Use `redactedAudio` instead.
246
252
  */
247
253
  redactions(id: string): Promise<RedactedAudioResponse> {
254
+ return this.redactedAudio(id);
255
+ }
256
+
257
+ /**
258
+ * Retrieve the redacted audio URL of a transcript.
259
+ * @param id - The identifier of the transcript.
260
+ * @returns A promise that resolves to the details of the redacted audio.
261
+ */
262
+ redactedAudio(id: string): Promise<RedactedAudioResponse> {
248
263
  return this.fetchJson<RedactedAudioResponse>(
249
264
  `/v2/transcript/${id}/redacted-audio`,
250
265
  );
251
266
  }
267
+
268
+ /**
269
+ * Retrieve the redacted audio file of a transcript.
270
+ * @param id - The identifier of the transcript.
271
+ * @returns A promise that resolves to the fetch HTTP response of the redacted audio file.
272
+ */
273
+ async redactedAudioFile(id: string): Promise<RedactedAudioFile> {
274
+ const { redacted_audio_url, status } = await this.redactedAudio(id);
275
+ if (status !== "redacted_audio_ready") {
276
+ throw new Error(`Redacted audio status is ${status}`);
277
+ }
278
+ const response = await fetch(redacted_audio_url);
279
+ if (!response.ok) {
280
+ throw new Error(`Failed to fetch redacted audio: ${response.statusText}`);
281
+ }
282
+ return {
283
+ arrayBuffer: response.arrayBuffer.bind(response),
284
+ blob: response.blob.bind(response),
285
+ body: response.body,
286
+ bodyUsed: response.bodyUsed,
287
+ };
288
+ }
252
289
  }
253
290
 
254
291
  function deprecateConformer2(params: { speech_model?: SpeechModel | null }) {
@@ -5,3 +5,12 @@ export * from "./services";
5
5
  export * from "./asyncapi.generated";
6
6
  export * from "./openapi.generated";
7
7
  export * from "./deprecated";
8
+
9
+ export type UserAgentItem = {
10
+ name: string;
11
+ version: string;
12
+ };
13
+
14
+ export type UserAgent = {
15
+ [component: string]: UserAgentItem | undefined | null | false;
16
+ };