assemblyai 4.4.6 → 4.4.7-beta.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.
@@ -0,0 +1,100 @@
1
+ # AssemblyAI JavaScript SDK
2
+
3
+ The AssemblyAI JavaScript SDK is developed using:
4
+
5
+ - Language: TypeScript
6
+ - Testing: Jest
7
+ - Bundler: Rollup
8
+ - Package manager: pnpm
9
+
10
+ ## Private vs public spec repository
11
+
12
+ This README.internal.md file and adjacent files are stored in
13
+ the [DeepLearning monorepo](#private-deeplearning-monorepo), which is private for AssemblyAI employees only.
14
+
15
+ Most files are also synced to the [public spec repo](#public-spec-repo) using [Copybara](#copybara).
16
+
17
+ ### Private DeepLearning monorepo
18
+
19
+ While most of the files in this folder are shared publicly using the public spec repo,
20
+ some files should only be kept in the [private repo](https://github.com/AssemblyAI/DeepLearning), like this README.internal.md.
21
+
22
+ The files that are synced are defined in the [Copybara configuration](./copy.bara.sky).
23
+
24
+ ### Public spec repo
25
+
26
+ [The public spec repo](https://github.com/AssemblyAI/assemblyai-node-sdk) has multiple purposes:
27
+
28
+ 1. Open-source the SDK code
29
+ 2. Accept feedback & contributions through issues and PRs
30
+ 3. Release the SDK to npmjs
31
+ 4. Publish the API reference using GitHub Actions
32
+
33
+ ## Copybara
34
+
35
+ We use [Copybara](https://github.com/google/copybara) to synchronize the private and public repo.
36
+ Copybara relies on [Bazel](https://bazel.build/) as part of the monorepo tooling.
37
+ To use the Copybara scripts, you must [set up Bazel](../../../docs/general/installation/05-bazel.md).
38
+
39
+ To create a PR with synced changes from the private to the public repo, run the following:
40
+
41
+ ```bash
42
+ ./copybara.sh sync_out --init-history
43
+ ## or the pnpm script
44
+ # pnpm copybara:pr
45
+ ```
46
+
47
+ To verify the synced changes before create the PR, you can also perform a _dry run_:
48
+
49
+ ```bash
50
+ ./copybara.sh dry_run --init-history
51
+ ## or the pnpm script
52
+ # pnpm copybara:dry-run
53
+ ```
54
+
55
+ The Copybara configuration is defined in [copy.bara.sky](./copy.bara.sky).
56
+
57
+ ## Contribute to the JavaScript SDK
58
+
59
+ If you want to contribute to the spec, you should do so via the [private monorepo](#private-deeplearning-monorepo).
60
+ The private repo enforces our internal rules and peer-reviews.
61
+
62
+ ### Set up
63
+
64
+ Follow these steps to set up the private repo:
65
+
66
+ 1. Clone the [monorepo](https://github.com/AssemblyAI/DeepLearning).
67
+ 2. [Set up Bazel](../../../docs/general/installation/05-bazel.md).
68
+ 3. [Set up pnpm (version 8)](https://pnpm.io/installation).
69
+
70
+ ### Make changes
71
+
72
+ Refer to the [CONTRIBUTING.md](./CONTRIBUTING.md) file for guidance on how to contribute.
73
+ The CONTRIBUTING.md file is written for contributors that don't work at AssemblyAI.
74
+
75
+ For AssemblyAI, the development workflow differs in the following ways:
76
+
77
+ - Instead of forking the public repo and cloning it, clone the monorepo.
78
+ - Get the latest changes from the `master` branch, not the `main` branch.
79
+ - Commit your changes, push your branch, and create a pull request (follow [the PR guidelines](../../../docs/general/pr_process.md)).
80
+ - Your PR will be checked using GitHub Actions. These checks run [Bazel](#Bazel) targets.
81
+
82
+ ### Push changes to public repo
83
+
84
+ Follow these steps to push your changes to the public spec repo:
85
+
86
+ 1. Make sure your changes have been merged into `master` via a PR.
87
+ 2. Git checkout `master` and get the latest changes.
88
+ 3. Run `pnpm copybara:dry-run` and verify the output is desired.
89
+ If not desired, update the [copy.bara.sky](./copy.bara.sky) file.
90
+ 4. Run `pnpm copybara:pr`.
91
+ 5. Go to the new PR, update the title and description.
92
+ 6. Ensure the checks pass for the PR before merging the PR to `main`.
93
+
94
+ ## Notes about the JavaScript SDK
95
+
96
+ ### Bazel
97
+
98
+ Bazel is used to automate and ensure code quality inside the DeepLearning monorepo.
99
+ GitHub Actions will run a variety of checks which run Bazel targets defined for the
100
+ whole repo, and additional targets defined in [BUILD.bazel](./BUILD.bazel).
@@ -48,6 +48,10 @@
48
48
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
49
49
  };
50
50
 
51
+ const DEFAULT_FETCH_INIT = {
52
+ cache: "no-store"
53
+ };
54
+
51
55
  const buildUserAgent = (userAgent) => defaultUserAgentString +
52
56
  (userAgent === false
53
57
  ? ""
@@ -102,10 +106,15 @@
102
106
  }
103
107
  fetch(input, init) {
104
108
  return __awaiter(this, void 0, void 0, function* () {
105
- var _a;
106
- init = init !== null && init !== void 0 ? init : {};
107
- let headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
108
- headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
109
+ init = Object.assign(Object.assign({}, DEFAULT_FETCH_INIT), init);
110
+ let headers = {
111
+ Authorization: this.params.apiKey,
112
+ "Content-Type": "application/json",
113
+ };
114
+ if (DEFAULT_FETCH_INIT === null || DEFAULT_FETCH_INIT === void 0 ? void 0 : DEFAULT_FETCH_INIT.headers)
115
+ headers = Object.assign(Object.assign({}, headers), DEFAULT_FETCH_INIT.headers);
116
+ if (init === null || init === void 0 ? void 0 : init.headers)
117
+ headers = Object.assign(Object.assign({}, headers), init.headers);
109
118
  if (this.userAgent) {
110
119
  headers["User-Agent"] = this.userAgent;
111
120
  // chromium browsers have a bug where the user agent can't be modified
@@ -115,7 +124,6 @@
115
124
  }
116
125
  }
117
126
  init.headers = headers;
118
- init.cache = "no-store";
119
127
  if (!input.startsWith("http"))
120
128
  input = this.params.baseUrl + input;
121
129
  const response = yield fetch(input, init);
@@ -126,7 +134,7 @@
126
134
  try {
127
135
  json = JSON.parse(text);
128
136
  }
129
- catch (_b) {
137
+ catch (_a) {
130
138
  /* empty */
131
139
  }
132
140
  if (json === null || json === void 0 ? void 0 : json.error)
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";function t(e,t,s,n){return new(s||(s=Promise))((function(i,o){function r(e){try{c(n.next(e))}catch(e){o(e)}}function a(e){try{c(n.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;let s="";"undefined"!=typeof navigator&&navigator.userAgent&&(s+=navigator.userAgent);const n={sdk:{name:"JavaScript",version:"4.4.6"}};"undefined"!=typeof process&&(process.versions.node&&-1===s.indexOf("Node")&&(n.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===s.indexOf("Bun")&&(n.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===s.indexOf("Deno")&&(n.runtime_env={name:"Deno",version:Deno.version.deno});class i{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},s+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},n),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,s){return t(this,void 0,void 0,(function*(){var t;let n=null!==(t=(s=null!=s?s:{}).headers)&&void 0!==t?t:{};n=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),this.userAgent&&(n["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(n["AssemblyAI-Agent"]=this.userAgent)),s.headers=n,s.cache="no-store",e.startsWith("http")||(e=this.params.baseUrl+e);const i=yield fetch(e,s);if(i.status>=400){let e;const t=yield i.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${i.status} ${i.statusText}`)}return i}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class o extends i{summary(e){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e)})}questionAnswer(e){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e)})}actionItems(e){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e)})}task(e){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e)})}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:r}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var a,c;const l=null!==(c=null!==(a=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==a?a:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==c?c:null===self||void 0===self?void 0:self.WebSocket,d=(e,t)=>t?new l(e,t):new l(e);var h;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(h||(h={}));const u={[h.BadSampleRate]:"Sample rate must be a positive integer",[h.AuthFailed]:"Not Authorized",[h.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[h.NonexistentSessionId]:"Session ID does not exist",[h.SessionExpired]:"Session has expired",[h.ClosedSession]:"Session is closed",[h.RateLimited]:"Rate limited",[h.UniqueSessionViolation]:"Unique session violation",[h.SessionTimeout]:"Session Timeout",[h.AudioTooShort]:"Audio too short",[h.AudioTooLong]:"Audio too long",[h.BadJson]:"Bad JSON",[h.BadSchema]:"Bad schema",[h.TooManyStreams]:"Too many streams",[h.Reconnected]:"Reconnected",[h.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class p extends Error{}const f='{"terminate_session":true}';class m{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=d(t.toString()):this.socket=d(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in h&&(t=u[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,o,r,a,c,l,d,h,u,f,m,v,y;const S=JSON.parse(t.toString());if("error"in S)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new p(S.error));else switch(S.message_type){case"SessionBegins":{const t={sessionId:S.session_id,expiresAt:new Date(S.expires_at)};e(t),null===(o=(i=this.listeners).open)||void 0===o||o.call(i,t);break}case"PartialTranscript":S.created=new Date(S.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,S),null===(l=(c=this.listeners)["transcript.partial"])||void 0===l||l.call(c,S);break;case"FinalTranscript":S.created=new Date(S.created),null===(h=(d=this.listeners).transcript)||void 0===h||h.call(d,S),null===(f=(u=this.listeners)["transcript.final"])||void 0===f||f.call(u,S);break;case"SessionInformation":null===(v=(m=this.listeners).session_information)||void 0===v||v.call(m,S);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new r({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return t(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(f),yield e}else this.socket.send(f);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class v extends i{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new m(t)}createTemporaryToken(e){return t(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}function y(e){return e.startsWith("http")||e.startsWith("https")||e.startsWith("data:")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class S extends i{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){w(e);const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){let t,s;if(w(e),"audio"in e){const{audio:n}=e,i=function(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}(e,["audio"]);if("string"==typeof n){const e=y(n);t=null!==e?yield this.files.upload(e):n.startsWith("data:")?yield this.files.upload(n):n}else t=yield this.files.upload(n);s=Object.assign(Object.assign({},i),{audio_url:t})}else s=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(s)})}))}create(e,s){return t(this,void 0,void 0,(function*(){var t;w(e);const n=y(e.audio_url);if(null!==n){const t=yield this.files.upload(n);e.audio_url=t}const i=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(t=null==s?void 0:s.poll)||void 0===t||t?yield this.waitUntilReady(i.id,s):i}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,n;const i=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(n=null==s?void 0:s.pollingTimeout)&&void 0!==n?n:-1,r=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(o>0&&Date.now()-r>o)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,i)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return t(this,void 0,void 0,(function*(){let t="/v2/transcript";"string"==typeof e?t=e:e&&(t=`${t}?${new URLSearchParams(Object.keys(e).map((t=>{var s;return[t,(null===(s=e[t])||void 0===s?void 0:s.toString())||""]})))}`);const s=yield this.fetchJson(t);for(const e of s.transcripts)e.created=new Date(e.created),e.completed&&(e.completed=new Date(e.completed));return s}))}delete(e){return this.fetchJson(`/v2/transcript/${e}`,{method:"DELETE"})}wordSearch(e,t){const s=new URLSearchParams({words:t.join(",")});return this.fetchJson(`/v2/transcript/${e}/word-search?${s.toString()}`)}sentences(e){return this.fetchJson(`/v2/transcript/${e}/sentences`)}paragraphs(e){return this.fetchJson(`/v2/transcript/${e}/paragraphs`)}subtitles(e){return t(this,arguments,void 0,(function*(e,t="srt",s){let n=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),n+=`?${e.toString()}`}const i=yield this.fetch(n);return yield i.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function w(e){e&&"conformer-2"===e.speech_model&&console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.")}class g extends i{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?e.startsWith("data:")?function(e){const t=e.split(","),s=t[0].match(/:(.*?);/)[1],n=atob(t[1]);let i=n.length;const o=new Uint8Array(i);for(;i--;)o[i]=n.charCodeAt(i);return new Blob([o],{type:s})}(e):yield function(e){return t(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new g(e),this.transcripts=new S(e,this.files),this.lemur=new o(e),this.realtime=new v(e)}},e.FileService=g,e.LemurService=o,e.RealtimeService=class extends m{},e.RealtimeServiceFactory=class extends v{},e.RealtimeTranscriber=m,e.RealtimeTranscriberFactory=v,e.TranscriptService=S}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).assemblyai={})}(this,(function(e){"use strict";function t(e,t,s,n){return new(s||(s=Promise))((function(i,o){function r(e){try{c(n.next(e))}catch(e){o(e)}}function a(e){try{c(n.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const s={cache:"no-store"};let n="";"undefined"!=typeof navigator&&navigator.userAgent&&(n+=navigator.userAgent);const i={sdk:{name:"JavaScript",version:"4.4.6"}};"undefined"!=typeof process&&(process.versions.node&&-1===n.indexOf("Node")&&(i.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===n.indexOf("Bun")&&(i.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===n.indexOf("Deno")&&(i.runtime_env={name:"Deno",version:Deno.version.deno});class o{constructor(e){var t;this.params=e,!1===e.userAgent?this.userAgent=void 0:this.userAgent=(t=e.userAgent||{},n+(!1===t?"":" AssemblyAI/1.0 ("+Object.entries(Object.assign(Object.assign({},i),t)).map((([e,t])=>t?`${e}=${t.name}/${t.version}`:"")).join(" ")+")"))}fetch(e,n){return t(this,void 0,void 0,(function*(){n=Object.assign(Object.assign({},s),n);let t={Authorization:this.params.apiKey,"Content-Type":"application/json"};(null==s?void 0:s.headers)&&(t=Object.assign(Object.assign({},t),s.headers)),(null==n?void 0:n.headers)&&(t=Object.assign(Object.assign({},t),n.headers)),this.userAgent&&(t["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(t["AssemblyAI-Agent"]=this.userAgent)),n.headers=t,e.startsWith("http")||(e=this.params.baseUrl+e);const i=yield fetch(e,n);if(i.status>=400){let e;const t=yield i.text();if(t){try{e=JSON.parse(t)}catch(e){}if(null==e?void 0:e.error)throw new Error(e.error);throw new Error(t)}throw new Error(`HTTP Error: ${i.status} ${i.statusText}`)}return i}))}fetchJson(e,s){return t(this,void 0,void 0,(function*(){return(yield this.fetch(e,s)).json()}))}}class r extends o{summary(e){return this.fetchJson("/lemur/v3/generate/summary",{method:"POST",body:JSON.stringify(e)})}questionAnswer(e){return this.fetchJson("/lemur/v3/generate/question-answer",{method:"POST",body:JSON.stringify(e)})}actionItems(e){return this.fetchJson("/lemur/v3/generate/action-items",{method:"POST",body:JSON.stringify(e)})}task(e){return this.fetchJson("/lemur/v3/generate/task",{method:"POST",body:JSON.stringify(e)})}purgeRequestData(e){return this.fetchJson(`/lemur/v3/${e}`,{method:"DELETE"})}}const{WritableStream:a}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var c,l;const d=null!==(l=null!==(c=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==c?c:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==l?l:null===self||void 0===self?void 0:self.WebSocket,h=(e,t)=>t?new d(e,t):new d(e);var u;!function(e){e[e.BadSampleRate=4e3]="BadSampleRate",e[e.AuthFailed=4001]="AuthFailed",e[e.InsufficientFundsOrFreeAccount=4002]="InsufficientFundsOrFreeAccount",e[e.NonexistentSessionId=4004]="NonexistentSessionId",e[e.SessionExpired=4008]="SessionExpired",e[e.ClosedSession=4010]="ClosedSession",e[e.RateLimited=4029]="RateLimited",e[e.UniqueSessionViolation=4030]="UniqueSessionViolation",e[e.SessionTimeout=4031]="SessionTimeout",e[e.AudioTooShort=4032]="AudioTooShort",e[e.AudioTooLong=4033]="AudioTooLong",e[e.BadJson=4100]="BadJson",e[e.BadSchema=4101]="BadSchema",e[e.TooManyStreams=4102]="TooManyStreams",e[e.Reconnected=4103]="Reconnected",e[e.ReconnectAttemptsExhausted=1013]="ReconnectAttemptsExhausted"}(u||(u={}));const p={[u.BadSampleRate]:"Sample rate must be a positive integer",[u.AuthFailed]:"Not Authorized",[u.InsufficientFundsOrFreeAccount]:"Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",[u.NonexistentSessionId]:"Session ID does not exist",[u.SessionExpired]:"Session has expired",[u.ClosedSession]:"Session is closed",[u.RateLimited]:"Rate limited",[u.UniqueSessionViolation]:"Unique session violation",[u.SessionTimeout]:"Session Timeout",[u.AudioTooShort]:"Audio too short",[u.AudioTooLong]:"Audio too long",[u.BadJson]:"Bad JSON",[u.BadSchema]:"Bad schema",[u.TooManyStreams]:"Too many streams",[u.Reconnected]:"Reconnected",[u.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class f extends Error{}const m='{"terminate_session":true}';class v{constructor(e){var t,s;if(this.listeners={},this.realtimeUrl=null!==(t=e.realtimeUrl)&&void 0!==t?t:"wss://api.assemblyai.com/v2/realtime/ws",this.sampleRate=null!==(s=e.sampleRate)&&void 0!==s?s:16e3,this.wordBoost=e.wordBoost,this.encoding=e.encoding,this.endUtteranceSilenceThreshold=e.endUtteranceSilenceThreshold,this.disablePartialTranscripts=e.disablePartialTranscripts,"token"in e&&e.token&&(this.token=e.token),"apiKey"in e&&e.apiKey&&(this.apiKey=e.apiKey),!this.token&&!this.apiKey)throw new Error("API key or temporary token is required.")}connectionUrl(){const e=new URL(this.realtimeUrl);if("wss:"!==e.protocol)throw new Error("Invalid protocol, must be wss");const t=new URLSearchParams;return this.token&&t.set("token",this.token),t.set("sample_rate",this.sampleRate.toString()),this.wordBoost&&this.wordBoost.length>0&&t.set("word_boost",JSON.stringify(this.wordBoost)),this.encoding&&t.set("encoding",this.encoding),t.set("enable_extra_session_information","true"),this.disablePartialTranscripts&&t.set("disable_partial_transcripts",this.disablePartialTranscripts.toString()),e.search=t.toString(),e}on(e,t){this.listeners[e]=t}connect(){return new Promise((e=>{if(this.socket)throw new Error("Already connected");const t=this.connectionUrl();this.token?this.socket=h(t.toString()):this.socket=h(t.toString(),{headers:{Authorization:this.apiKey}}),this.socket.binaryType="arraybuffer",this.socket.onopen=()=>{void 0!==this.endUtteranceSilenceThreshold&&null!==this.endUtteranceSilenceThreshold&&this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold)},this.socket.onclose=({code:e,reason:t})=>{var s,n;t||e in u&&(t=p[e]),null===(n=(s=this.listeners).close)||void 0===n||n.call(s,e,t)},this.socket.onerror=e=>{var t,s,n,i;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(i=(n=this.listeners).error)||void 0===i||i.call(n,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,n,i,o,r,a,c,l,d,h,u,p,m,v,y;const S=JSON.parse(t.toString());if("error"in S)null===(n=(s=this.listeners).error)||void 0===n||n.call(s,new f(S.error));else switch(S.message_type){case"SessionBegins":{const t={sessionId:S.session_id,expiresAt:new Date(S.expires_at)};e(t),null===(o=(i=this.listeners).open)||void 0===o||o.call(i,t);break}case"PartialTranscript":S.created=new Date(S.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,S),null===(l=(c=this.listeners)["transcript.partial"])||void 0===l||l.call(c,S);break;case"FinalTranscript":S.created=new Date(S.created),null===(h=(d=this.listeners).transcript)||void 0===h||h.call(d,S),null===(p=(u=this.listeners)["transcript.final"])||void 0===p||p.call(u,S);break;case"SessionInformation":null===(v=(m=this.listeners).session_information)||void 0===v||v.call(m,S);break;case"SessionTerminated":null===(y=this.sessionTerminatedResolve)||void 0===y||y.call(this)}}}))}sendAudio(e){this.send(e)}stream(){return new a({write:e=>{this.sendAudio(e)}})}forceEndUtterance(){this.send('{"force_end_utterance":true}')}configureEndUtteranceSilenceThreshold(e){this.send(`{"end_utterance_silence_threshold":${e}}`)}send(e){if(!this.socket||this.socket.readyState!==this.socket.OPEN)throw new Error("Socket is not open for communication");this.socket.send(e)}close(){return t(this,arguments,void 0,(function*(e=!0){var t;if(this.socket){if(this.socket.readyState===this.socket.OPEN)if(e){const e=new Promise((e=>{this.sessionTerminatedResolve=e}));this.socket.send(m),yield e}else this.socket.send(m);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class y extends o{constructor(e){super(e),this.rtFactoryParams=e}createService(e){return this.transcriber(e)}transcriber(e){const t=Object.assign({},e);return t.token||t.apiKey||(t.apiKey=this.rtFactoryParams.apiKey),new v(t)}createTemporaryToken(e){return t(this,void 0,void 0,(function*(){return(yield this.fetchJson("/v2/realtime/token",{method:"POST",body:JSON.stringify(e)})).token}))}}function S(e){return e.startsWith("http")||e.startsWith("https")||e.startsWith("data:")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class g extends o{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){b(e);const t=yield this.submit(e);return yield this.waitUntilReady(t.id,s)}))}submit(e){return t(this,void 0,void 0,(function*(){let t,s;if(b(e),"audio"in e){const{audio:n}=e,i=function(e,t){var s={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(s[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(n=Object.getOwnPropertySymbols(e);i<n.length;i++)t.indexOf(n[i])<0&&Object.prototype.propertyIsEnumerable.call(e,n[i])&&(s[n[i]]=e[n[i]])}return s}(e,["audio"]);if("string"==typeof n){const e=S(n);t=null!==e?yield this.files.upload(e):n.startsWith("data:")?yield this.files.upload(n):n}else t=yield this.files.upload(n);s=Object.assign(Object.assign({},i),{audio_url:t})}else s=e;return yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(s)})}))}create(e,s){return t(this,void 0,void 0,(function*(){var t;b(e);const n=S(e.audio_url);if(null!==n){const t=yield this.files.upload(n);e.audio_url=t}const i=yield this.fetchJson("/v2/transcript",{method:"POST",body:JSON.stringify(e)});return null===(t=null==s?void 0:s.poll)||void 0===t||t?yield this.waitUntilReady(i.id,s):i}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,n;const i=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(n=null==s?void 0:s.pollingTimeout)&&void 0!==n?n:-1,r=Date.now();for(;;){const t=yield this.get(e);if("completed"===t.status||"error"===t.status)return t;if(o>0&&Date.now()-r>o)throw new Error("Polling timeout");yield new Promise((e=>setTimeout(e,i)))}}))}get(e){return this.fetchJson(`/v2/transcript/${e}`)}list(e){return t(this,void 0,void 0,(function*(){let t="/v2/transcript";"string"==typeof e?t=e:e&&(t=`${t}?${new URLSearchParams(Object.keys(e).map((t=>{var s;return[t,(null===(s=e[t])||void 0===s?void 0:s.toString())||""]})))}`);const s=yield this.fetchJson(t);for(const e of s.transcripts)e.created=new Date(e.created),e.completed&&(e.completed=new Date(e.completed));return s}))}delete(e){return this.fetchJson(`/v2/transcript/${e}`,{method:"DELETE"})}wordSearch(e,t){const s=new URLSearchParams({words:t.join(",")});return this.fetchJson(`/v2/transcript/${e}/word-search?${s.toString()}`)}sentences(e){return this.fetchJson(`/v2/transcript/${e}/sentences`)}paragraphs(e){return this.fetchJson(`/v2/transcript/${e}/paragraphs`)}subtitles(e){return t(this,arguments,void 0,(function*(e,t="srt",s){let n=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),n+=`?${e.toString()}`}const i=yield this.fetch(n);return yield i.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function b(e){e&&"conformer-2"===e.speech_model&&console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.")}class w extends o{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof e?e.startsWith("data:")?function(e){const t=e.split(","),s=t[0].match(/:(.*?);/)[1],n=atob(t[1]);let i=n.length;const o=new Uint8Array(i);for(;i--;)o[i]=n.charCodeAt(i);return new Blob([o],{type:s})}(e):yield function(e){return t(this,void 0,void 0,(function*(){throw new Error("Interacting with the file system is not supported in this environment.")}))}():e;return(yield this.fetchJson("/v2/upload",{method:"POST",body:s,headers:{"Content-Type":"application/octet-stream"},duplex:"half"})).upload_url}))}}e.AssemblyAI=class{constructor(e){e.baseUrl=e.baseUrl||"https://api.assemblyai.com",e.baseUrl&&e.baseUrl.endsWith("/")&&(e.baseUrl=e.baseUrl.slice(0,-1)),this.files=new w(e),this.transcripts=new g(e,this.files),this.lemur=new r(e),this.realtime=new y(e)}},e.FileService=w,e.LemurService=r,e.RealtimeService=class extends v{},e.RealtimeServiceFactory=class extends y{},e.RealtimeTranscriber=v,e.RealtimeTranscriberFactory=y,e.TranscriptService=g}));
package/dist/browser.mjs CHANGED
@@ -1,3 +1,7 @@
1
+ const DEFAULT_FETCH_INIT = {
2
+ cache: "no-store"
3
+ };
4
+
1
5
  const buildUserAgent = (userAgent) => defaultUserAgentString +
2
6
  (userAgent === false
3
7
  ? ""
@@ -51,13 +55,15 @@ class BaseService {
51
55
  }
52
56
  }
53
57
  async fetch(input, init) {
54
- init = init ?? {};
55
- let headers = init.headers ?? {};
56
- headers = {
58
+ init = { ...DEFAULT_FETCH_INIT, ...init };
59
+ let headers = {
57
60
  Authorization: this.params.apiKey,
58
61
  "Content-Type": "application/json",
59
- ...init.headers,
60
62
  };
63
+ if (DEFAULT_FETCH_INIT?.headers)
64
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
65
+ if (init?.headers)
66
+ headers = { ...headers, ...init.headers };
61
67
  if (this.userAgent) {
62
68
  headers["User-Agent"] = this.userAgent;
63
69
  // chromium browsers have a bug where the user agent can't be modified
@@ -67,7 +73,6 @@ class BaseService {
67
73
  }
68
74
  }
69
75
  init.headers = headers;
70
- init.cache = "no-store";
71
76
  if (!input.startsWith("http"))
72
77
  input = this.params.baseUrl + input;
73
78
  const response = await fetch(input, init);
package/dist/bun.mjs CHANGED
@@ -1,5 +1,9 @@
1
1
  import ws from 'ws';
2
2
 
3
+ const DEFAULT_FETCH_INIT = {
4
+ cache: "no-store"
5
+ };
6
+
3
7
  const buildUserAgent = (userAgent) => defaultUserAgentString +
4
8
  (userAgent === false
5
9
  ? ""
@@ -53,13 +57,15 @@ class BaseService {
53
57
  }
54
58
  }
55
59
  async fetch(input, init) {
56
- init = init ?? {};
57
- let headers = init.headers ?? {};
58
- headers = {
60
+ init = { ...DEFAULT_FETCH_INIT, ...init };
61
+ let headers = {
59
62
  Authorization: this.params.apiKey,
60
63
  "Content-Type": "application/json",
61
- ...init.headers,
62
64
  };
65
+ if (DEFAULT_FETCH_INIT?.headers)
66
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
67
+ if (init?.headers)
68
+ headers = { ...headers, ...init.headers };
63
69
  if (this.userAgent) {
64
70
  headers["User-Agent"] = this.userAgent;
65
71
  // chromium browsers have a bug where the user agent can't be modified
@@ -69,7 +75,6 @@ class BaseService {
69
75
  }
70
76
  }
71
77
  init.headers = headers;
72
- init.cache = "no-store";
73
78
  if (!input.startsWith("http"))
74
79
  input = this.params.baseUrl + input;
75
80
  const response = await fetch(input, init);
package/dist/deno.mjs CHANGED
@@ -1,5 +1,9 @@
1
1
  import ws from 'ws';
2
2
 
3
+ const DEFAULT_FETCH_INIT = {
4
+ cache: "no-store"
5
+ };
6
+
3
7
  const buildUserAgent = (userAgent) => defaultUserAgentString +
4
8
  (userAgent === false
5
9
  ? ""
@@ -53,13 +57,15 @@ class BaseService {
53
57
  }
54
58
  }
55
59
  async fetch(input, init) {
56
- init = init ?? {};
57
- let headers = init.headers ?? {};
58
- headers = {
60
+ init = { ...DEFAULT_FETCH_INIT, ...init };
61
+ let headers = {
59
62
  Authorization: this.params.apiKey,
60
63
  "Content-Type": "application/json",
61
- ...init.headers,
62
64
  };
65
+ if (DEFAULT_FETCH_INIT?.headers)
66
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
67
+ if (init?.headers)
68
+ headers = { ...headers, ...init.headers };
63
69
  if (this.userAgent) {
64
70
  headers["User-Agent"] = this.userAgent;
65
71
  // chromium browsers have a bug where the user agent can't be modified
@@ -69,7 +75,6 @@ class BaseService {
69
75
  }
70
76
  }
71
77
  init.headers = headers;
72
- init.cache = "no-store";
73
78
  if (!input.startsWith("http"))
74
79
  input = this.params.baseUrl + input;
75
80
  const response = await fetch(input, init);
package/dist/index.cjs CHANGED
@@ -46,6 +46,10 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
46
46
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
47
47
  };
48
48
 
49
+ const DEFAULT_FETCH_INIT = {
50
+ cache: "no-store"
51
+ };
52
+
49
53
  const buildUserAgent = (userAgent) => defaultUserAgentString +
50
54
  (userAgent === false
51
55
  ? ""
@@ -100,10 +104,15 @@ class BaseService {
100
104
  }
101
105
  fetch(input, init) {
102
106
  return __awaiter(this, void 0, void 0, function* () {
103
- var _a;
104
- init = init !== null && init !== void 0 ? init : {};
105
- let headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
106
- headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
107
+ init = Object.assign(Object.assign({}, DEFAULT_FETCH_INIT), init);
108
+ let headers = {
109
+ Authorization: this.params.apiKey,
110
+ "Content-Type": "application/json",
111
+ };
112
+ if (DEFAULT_FETCH_INIT === null || DEFAULT_FETCH_INIT === void 0 ? void 0 : DEFAULT_FETCH_INIT.headers)
113
+ headers = Object.assign(Object.assign({}, headers), DEFAULT_FETCH_INIT.headers);
114
+ if (init === null || init === void 0 ? void 0 : init.headers)
115
+ headers = Object.assign(Object.assign({}, headers), init.headers);
107
116
  if (this.userAgent) {
108
117
  headers["User-Agent"] = this.userAgent;
109
118
  // chromium browsers have a bug where the user agent can't be modified
@@ -113,7 +122,6 @@ class BaseService {
113
122
  }
114
123
  }
115
124
  init.headers = headers;
116
- init.cache = "no-store";
117
125
  if (!input.startsWith("http"))
118
126
  input = this.params.baseUrl + input;
119
127
  const response = yield fetch(input, init);
@@ -124,7 +132,7 @@ class BaseService {
124
132
  try {
125
133
  json = JSON.parse(text);
126
134
  }
127
- catch (_b) {
135
+ catch (_a) {
128
136
  /* empty */
129
137
  }
130
138
  if (json === null || json === void 0 ? void 0 : json.error)
package/dist/index.mjs CHANGED
@@ -44,6 +44,10 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
44
44
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
45
45
  };
46
46
 
47
+ const DEFAULT_FETCH_INIT = {
48
+ cache: "no-store"
49
+ };
50
+
47
51
  const buildUserAgent = (userAgent) => defaultUserAgentString +
48
52
  (userAgent === false
49
53
  ? ""
@@ -98,10 +102,15 @@ class BaseService {
98
102
  }
99
103
  fetch(input, init) {
100
104
  return __awaiter(this, void 0, void 0, function* () {
101
- var _a;
102
- init = init !== null && init !== void 0 ? init : {};
103
- let headers = (_a = init.headers) !== null && _a !== void 0 ? _a : {};
104
- headers = Object.assign({ Authorization: this.params.apiKey, "Content-Type": "application/json" }, init.headers);
105
+ init = Object.assign(Object.assign({}, DEFAULT_FETCH_INIT), init);
106
+ let headers = {
107
+ Authorization: this.params.apiKey,
108
+ "Content-Type": "application/json",
109
+ };
110
+ if (DEFAULT_FETCH_INIT === null || DEFAULT_FETCH_INIT === void 0 ? void 0 : DEFAULT_FETCH_INIT.headers)
111
+ headers = Object.assign(Object.assign({}, headers), DEFAULT_FETCH_INIT.headers);
112
+ if (init === null || init === void 0 ? void 0 : init.headers)
113
+ headers = Object.assign(Object.assign({}, headers), init.headers);
105
114
  if (this.userAgent) {
106
115
  headers["User-Agent"] = this.userAgent;
107
116
  // chromium browsers have a bug where the user agent can't be modified
@@ -111,7 +120,6 @@ class BaseService {
111
120
  }
112
121
  }
113
122
  init.headers = headers;
114
- init.cache = "no-store";
115
123
  if (!input.startsWith("http"))
116
124
  input = this.params.baseUrl + input;
117
125
  const response = yield fetch(input, init);
@@ -122,7 +130,7 @@ class BaseService {
122
130
  try {
123
131
  json = JSON.parse(text);
124
132
  }
125
- catch (_b) {
133
+ catch (_a) {
126
134
  /* empty */
127
135
  }
128
136
  if (json === null || json === void 0 ? void 0 : json.error)
package/dist/node.cjs CHANGED
@@ -5,6 +5,10 @@ var ws = require('ws');
5
5
  var fs = require('fs');
6
6
  var stream = require('stream');
7
7
 
8
+ const DEFAULT_FETCH_INIT = {
9
+ cache: "no-store"
10
+ };
11
+
8
12
  const buildUserAgent = (userAgent) => defaultUserAgentString +
9
13
  (userAgent === false
10
14
  ? ""
@@ -58,13 +62,15 @@ class BaseService {
58
62
  }
59
63
  }
60
64
  async fetch(input, init) {
61
- init = init ?? {};
62
- let headers = init.headers ?? {};
63
- headers = {
65
+ init = { ...DEFAULT_FETCH_INIT, ...init };
66
+ let headers = {
64
67
  Authorization: this.params.apiKey,
65
68
  "Content-Type": "application/json",
66
- ...init.headers,
67
69
  };
70
+ if (DEFAULT_FETCH_INIT?.headers)
71
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
72
+ if (init?.headers)
73
+ headers = { ...headers, ...init.headers };
68
74
  if (this.userAgent) {
69
75
  headers["User-Agent"] = this.userAgent;
70
76
  // chromium browsers have a bug where the user agent can't be modified
@@ -74,7 +80,6 @@ class BaseService {
74
80
  }
75
81
  }
76
82
  init.headers = headers;
77
- init.cache = "no-store";
78
83
  if (!input.startsWith("http"))
79
84
  input = this.params.baseUrl + input;
80
85
  const response = await fetch(input, init);
package/dist/node.mjs CHANGED
@@ -3,6 +3,10 @@ import ws from 'ws';
3
3
  import { createReadStream } from 'fs';
4
4
  import { Readable } from 'stream';
5
5
 
6
+ const DEFAULT_FETCH_INIT = {
7
+ cache: "no-store"
8
+ };
9
+
6
10
  const buildUserAgent = (userAgent) => defaultUserAgentString +
7
11
  (userAgent === false
8
12
  ? ""
@@ -56,13 +60,15 @@ class BaseService {
56
60
  }
57
61
  }
58
62
  async fetch(input, init) {
59
- init = init ?? {};
60
- let headers = init.headers ?? {};
61
- headers = {
63
+ init = { ...DEFAULT_FETCH_INIT, ...init };
64
+ let headers = {
62
65
  Authorization: this.params.apiKey,
63
66
  "Content-Type": "application/json",
64
- ...init.headers,
65
67
  };
68
+ if (DEFAULT_FETCH_INIT?.headers)
69
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
70
+ if (init?.headers)
71
+ headers = { ...headers, ...init.headers };
66
72
  if (this.userAgent) {
67
73
  headers["User-Agent"] = this.userAgent;
68
74
  // chromium browsers have a bug where the user agent can't be modified
@@ -72,7 +78,6 @@ class BaseService {
72
78
  }
73
79
  }
74
80
  init.headers = headers;
75
- init.cache = "no-store";
76
81
  if (!input.startsWith("http"))
77
82
  input = this.params.baseUrl + input;
78
83
  const response = await fetch(input, init);
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_FETCH_INIT: Record<string, unknown>;
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_FETCH_INIT: Record<string, unknown>;
@@ -0,0 +1,689 @@
1
+ import ws from 'ws';
2
+
3
+ const DEFAULT_FETCH_INIT = {};
4
+
5
+ const buildUserAgent = (userAgent) => defaultUserAgentString +
6
+ (userAgent === false
7
+ ? ""
8
+ : " AssemblyAI/1.0 (" +
9
+ Object.entries({ ...defaultUserAgent, ...userAgent })
10
+ .map(([key, item]) => item ? `${key}=${item.name}/${item.version}` : "")
11
+ .join(" ") +
12
+ ")");
13
+ let defaultUserAgentString = "";
14
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
15
+ defaultUserAgentString += navigator.userAgent;
16
+ }
17
+ const defaultUserAgent = {
18
+ sdk: { name: "JavaScript", version: "4.4.6" },
19
+ };
20
+ if (typeof process !== "undefined") {
21
+ if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
22
+ defaultUserAgent.runtime_env = {
23
+ name: "Node",
24
+ version: process.versions.node,
25
+ };
26
+ }
27
+ if (process.versions.bun && defaultUserAgentString.indexOf("Bun") === -1) {
28
+ defaultUserAgent.runtime_env = {
29
+ name: "Bun",
30
+ version: process.versions.bun,
31
+ };
32
+ }
33
+ }
34
+ if (typeof Deno !== "undefined") {
35
+ if (process.versions.bun && defaultUserAgentString.indexOf("Deno") === -1) {
36
+ defaultUserAgent.runtime_env = { name: "Deno", version: Deno.version.deno };
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Base class for services that communicate with the API.
42
+ */
43
+ class BaseService {
44
+ /**
45
+ * Create a new service.
46
+ * @param params - The parameters to use for the service.
47
+ */
48
+ constructor(params) {
49
+ this.params = params;
50
+ if (params.userAgent === false) {
51
+ this.userAgent = undefined;
52
+ }
53
+ else {
54
+ this.userAgent = buildUserAgent(params.userAgent || {});
55
+ }
56
+ }
57
+ async fetch(input, init) {
58
+ init = { ...DEFAULT_FETCH_INIT, ...init };
59
+ let headers = {
60
+ Authorization: this.params.apiKey,
61
+ "Content-Type": "application/json",
62
+ };
63
+ if (DEFAULT_FETCH_INIT?.headers)
64
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
65
+ if (init?.headers)
66
+ headers = { ...headers, ...init.headers };
67
+ if (this.userAgent) {
68
+ headers["User-Agent"] = this.userAgent;
69
+ // chromium browsers have a bug where the user agent can't be modified
70
+ if (typeof window !== "undefined" && "chrome" in window) {
71
+ headers["AssemblyAI-Agent"] =
72
+ this.userAgent;
73
+ }
74
+ }
75
+ init.headers = headers;
76
+ if (!input.startsWith("http"))
77
+ input = this.params.baseUrl + input;
78
+ const response = await fetch(input, init);
79
+ if (response.status >= 400) {
80
+ let json;
81
+ const text = await response.text();
82
+ if (text) {
83
+ try {
84
+ json = JSON.parse(text);
85
+ }
86
+ catch {
87
+ /* empty */
88
+ }
89
+ if (json?.error)
90
+ throw new Error(json.error);
91
+ throw new Error(text);
92
+ }
93
+ throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
94
+ }
95
+ return response;
96
+ }
97
+ async fetchJson(input, init) {
98
+ const response = await this.fetch(input, init);
99
+ return response.json();
100
+ }
101
+ }
102
+
103
+ class LemurService extends BaseService {
104
+ summary(params) {
105
+ return this.fetchJson("/lemur/v3/generate/summary", {
106
+ method: "POST",
107
+ body: JSON.stringify(params),
108
+ });
109
+ }
110
+ questionAnswer(params) {
111
+ return this.fetchJson("/lemur/v3/generate/question-answer", {
112
+ method: "POST",
113
+ body: JSON.stringify(params),
114
+ });
115
+ }
116
+ actionItems(params) {
117
+ return this.fetchJson("/lemur/v3/generate/action-items", {
118
+ method: "POST",
119
+ body: JSON.stringify(params),
120
+ });
121
+ }
122
+ task(params) {
123
+ return this.fetchJson("/lemur/v3/generate/task", {
124
+ method: "POST",
125
+ body: JSON.stringify(params),
126
+ });
127
+ }
128
+ /**
129
+ * Delete the data for a previously submitted LeMUR request.
130
+ * @param id - ID of the LeMUR request
131
+ */
132
+ purgeRequestData(id) {
133
+ return this.fetchJson(`/lemur/v3/${id}`, {
134
+ method: "DELETE",
135
+ });
136
+ }
137
+ }
138
+
139
+ const { WritableStream } = typeof window !== "undefined"
140
+ ? window
141
+ : typeof global !== "undefined"
142
+ ? global
143
+ : globalThis;
144
+
145
+ const factory = (url, params) => new ws(url, params);
146
+
147
+ var RealtimeErrorType;
148
+ (function (RealtimeErrorType) {
149
+ RealtimeErrorType[RealtimeErrorType["BadSampleRate"] = 4000] = "BadSampleRate";
150
+ RealtimeErrorType[RealtimeErrorType["AuthFailed"] = 4001] = "AuthFailed";
151
+ // Both InsufficientFunds and FreeAccount error use 4002
152
+ RealtimeErrorType[RealtimeErrorType["InsufficientFundsOrFreeAccount"] = 4002] = "InsufficientFundsOrFreeAccount";
153
+ RealtimeErrorType[RealtimeErrorType["NonexistentSessionId"] = 4004] = "NonexistentSessionId";
154
+ RealtimeErrorType[RealtimeErrorType["SessionExpired"] = 4008] = "SessionExpired";
155
+ RealtimeErrorType[RealtimeErrorType["ClosedSession"] = 4010] = "ClosedSession";
156
+ RealtimeErrorType[RealtimeErrorType["RateLimited"] = 4029] = "RateLimited";
157
+ RealtimeErrorType[RealtimeErrorType["UniqueSessionViolation"] = 4030] = "UniqueSessionViolation";
158
+ RealtimeErrorType[RealtimeErrorType["SessionTimeout"] = 4031] = "SessionTimeout";
159
+ RealtimeErrorType[RealtimeErrorType["AudioTooShort"] = 4032] = "AudioTooShort";
160
+ RealtimeErrorType[RealtimeErrorType["AudioTooLong"] = 4033] = "AudioTooLong";
161
+ RealtimeErrorType[RealtimeErrorType["BadJson"] = 4100] = "BadJson";
162
+ RealtimeErrorType[RealtimeErrorType["BadSchema"] = 4101] = "BadSchema";
163
+ RealtimeErrorType[RealtimeErrorType["TooManyStreams"] = 4102] = "TooManyStreams";
164
+ RealtimeErrorType[RealtimeErrorType["Reconnected"] = 4103] = "Reconnected";
165
+ RealtimeErrorType[RealtimeErrorType["ReconnectAttemptsExhausted"] = 1013] = "ReconnectAttemptsExhausted";
166
+ })(RealtimeErrorType || (RealtimeErrorType = {}));
167
+ const RealtimeErrorMessages = {
168
+ [RealtimeErrorType.BadSampleRate]: "Sample rate must be a positive integer",
169
+ [RealtimeErrorType.AuthFailed]: "Not Authorized",
170
+ [RealtimeErrorType.InsufficientFundsOrFreeAccount]: "Insufficient funds or you are using a free account. This feature is paid-only and requires you to add a credit card. Please visit https://assemblyai.com/dashboard/ to add a credit card to your account.",
171
+ [RealtimeErrorType.NonexistentSessionId]: "Session ID does not exist",
172
+ [RealtimeErrorType.SessionExpired]: "Session has expired",
173
+ [RealtimeErrorType.ClosedSession]: "Session is closed",
174
+ [RealtimeErrorType.RateLimited]: "Rate limited",
175
+ [RealtimeErrorType.UniqueSessionViolation]: "Unique session violation",
176
+ [RealtimeErrorType.SessionTimeout]: "Session Timeout",
177
+ [RealtimeErrorType.AudioTooShort]: "Audio too short",
178
+ [RealtimeErrorType.AudioTooLong]: "Audio too long",
179
+ [RealtimeErrorType.BadJson]: "Bad JSON",
180
+ [RealtimeErrorType.BadSchema]: "Bad schema",
181
+ [RealtimeErrorType.TooManyStreams]: "Too many streams",
182
+ [RealtimeErrorType.Reconnected]: "Reconnected",
183
+ [RealtimeErrorType.ReconnectAttemptsExhausted]: "Reconnect attempts exhausted",
184
+ };
185
+ class RealtimeError extends Error {
186
+ }
187
+
188
+ const defaultRealtimeUrl = "wss://api.assemblyai.com/v2/realtime/ws";
189
+ const forceEndOfUtteranceMessage = `{"force_end_utterance":true}`;
190
+ const terminateSessionMessage = `{"terminate_session":true}`;
191
+ class RealtimeTranscriber {
192
+ constructor(params) {
193
+ this.listeners = {};
194
+ this.realtimeUrl = params.realtimeUrl ?? defaultRealtimeUrl;
195
+ this.sampleRate = params.sampleRate ?? 16_000;
196
+ this.wordBoost = params.wordBoost;
197
+ this.encoding = params.encoding;
198
+ this.endUtteranceSilenceThreshold = params.endUtteranceSilenceThreshold;
199
+ this.disablePartialTranscripts = params.disablePartialTranscripts;
200
+ if ("token" in params && params.token)
201
+ this.token = params.token;
202
+ if ("apiKey" in params && params.apiKey)
203
+ this.apiKey = params.apiKey;
204
+ if (!(this.token || this.apiKey)) {
205
+ throw new Error("API key or temporary token is required.");
206
+ }
207
+ }
208
+ connectionUrl() {
209
+ const url = new URL(this.realtimeUrl);
210
+ if (url.protocol !== "wss:") {
211
+ throw new Error("Invalid protocol, must be wss");
212
+ }
213
+ const searchParams = new URLSearchParams();
214
+ if (this.token) {
215
+ searchParams.set("token", this.token);
216
+ }
217
+ searchParams.set("sample_rate", this.sampleRate.toString());
218
+ if (this.wordBoost && this.wordBoost.length > 0) {
219
+ searchParams.set("word_boost", JSON.stringify(this.wordBoost));
220
+ }
221
+ if (this.encoding) {
222
+ searchParams.set("encoding", this.encoding);
223
+ }
224
+ searchParams.set("enable_extra_session_information", "true");
225
+ if (this.disablePartialTranscripts) {
226
+ searchParams.set("disable_partial_transcripts", this.disablePartialTranscripts.toString());
227
+ }
228
+ url.search = searchParams.toString();
229
+ return url;
230
+ }
231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
232
+ on(event, listener) {
233
+ this.listeners[event] = listener;
234
+ }
235
+ connect() {
236
+ return new Promise((resolve) => {
237
+ if (this.socket) {
238
+ throw new Error("Already connected");
239
+ }
240
+ const url = this.connectionUrl();
241
+ if (this.token) {
242
+ this.socket = factory(url.toString());
243
+ }
244
+ else {
245
+ this.socket = factory(url.toString(), {
246
+ headers: { Authorization: this.apiKey },
247
+ });
248
+ }
249
+ this.socket.binaryType = "arraybuffer";
250
+ this.socket.onopen = () => {
251
+ if (this.endUtteranceSilenceThreshold === undefined ||
252
+ this.endUtteranceSilenceThreshold === null) {
253
+ return;
254
+ }
255
+ this.configureEndUtteranceSilenceThreshold(this.endUtteranceSilenceThreshold);
256
+ };
257
+ this.socket.onclose = ({ code, reason }) => {
258
+ if (!reason) {
259
+ if (code in RealtimeErrorType) {
260
+ reason = RealtimeErrorMessages[code];
261
+ }
262
+ }
263
+ this.listeners.close?.(code, reason);
264
+ };
265
+ this.socket.onerror = (event) => {
266
+ if (event.error)
267
+ this.listeners.error?.(event.error);
268
+ else
269
+ this.listeners.error?.(new Error(event.message));
270
+ };
271
+ this.socket.onmessage = ({ data }) => {
272
+ const message = JSON.parse(data.toString());
273
+ if ("error" in message) {
274
+ this.listeners.error?.(new RealtimeError(message.error));
275
+ return;
276
+ }
277
+ switch (message.message_type) {
278
+ case "SessionBegins": {
279
+ const openObject = {
280
+ sessionId: message.session_id,
281
+ expiresAt: new Date(message.expires_at),
282
+ };
283
+ resolve(openObject);
284
+ this.listeners.open?.(openObject);
285
+ break;
286
+ }
287
+ case "PartialTranscript": {
288
+ // message.created is actually a string when coming from the socket
289
+ message.created = new Date(message.created);
290
+ this.listeners.transcript?.(message);
291
+ this.listeners["transcript.partial"]?.(message);
292
+ break;
293
+ }
294
+ case "FinalTranscript": {
295
+ // message.created is actually a string when coming from the socket
296
+ message.created = new Date(message.created);
297
+ this.listeners.transcript?.(message);
298
+ this.listeners["transcript.final"]?.(message);
299
+ break;
300
+ }
301
+ case "SessionInformation": {
302
+ this.listeners.session_information?.(message);
303
+ break;
304
+ }
305
+ case "SessionTerminated": {
306
+ this.sessionTerminatedResolve?.();
307
+ break;
308
+ }
309
+ }
310
+ };
311
+ });
312
+ }
313
+ sendAudio(audio) {
314
+ this.send(audio);
315
+ }
316
+ stream() {
317
+ return new WritableStream({
318
+ write: (chunk) => {
319
+ this.sendAudio(chunk);
320
+ },
321
+ });
322
+ }
323
+ /**
324
+ * Manually end an utterance
325
+ */
326
+ forceEndUtterance() {
327
+ this.send(forceEndOfUtteranceMessage);
328
+ }
329
+ /**
330
+ * Configure the threshold for how long to wait before ending an utterance. Default is 700ms.
331
+ * @param threshold - The duration of the end utterance silence threshold in milliseconds.
332
+ * This value must be an integer between 0 and 20_000.
333
+ */
334
+ configureEndUtteranceSilenceThreshold(threshold) {
335
+ this.send(`{"end_utterance_silence_threshold":${threshold}}`);
336
+ }
337
+ send(data) {
338
+ if (!this.socket || this.socket.readyState !== this.socket.OPEN) {
339
+ throw new Error("Socket is not open for communication");
340
+ }
341
+ this.socket.send(data);
342
+ }
343
+ async close(waitForSessionTermination = true) {
344
+ if (this.socket) {
345
+ if (this.socket.readyState === this.socket.OPEN) {
346
+ if (waitForSessionTermination) {
347
+ const sessionTerminatedPromise = new Promise((resolve) => {
348
+ this.sessionTerminatedResolve = resolve;
349
+ });
350
+ this.socket.send(terminateSessionMessage);
351
+ await sessionTerminatedPromise;
352
+ }
353
+ else {
354
+ this.socket.send(terminateSessionMessage);
355
+ }
356
+ }
357
+ if (this.socket?.removeAllListeners)
358
+ this.socket.removeAllListeners();
359
+ this.socket.close();
360
+ }
361
+ this.listeners = {};
362
+ this.socket = undefined;
363
+ }
364
+ }
365
+ /**
366
+ * @deprecated Use RealtimeTranscriber instead
367
+ */
368
+ class RealtimeService extends RealtimeTranscriber {
369
+ }
370
+
371
+ class RealtimeTranscriberFactory extends BaseService {
372
+ constructor(params) {
373
+ super(params);
374
+ this.rtFactoryParams = params;
375
+ }
376
+ /**
377
+ * @deprecated Use transcriber(...) instead
378
+ */
379
+ createService(params) {
380
+ return this.transcriber(params);
381
+ }
382
+ transcriber(params) {
383
+ const serviceParams = { ...params };
384
+ if (!serviceParams.token && !serviceParams.apiKey) {
385
+ serviceParams.apiKey = this.rtFactoryParams.apiKey;
386
+ }
387
+ return new RealtimeTranscriber(serviceParams);
388
+ }
389
+ async createTemporaryToken(params) {
390
+ const data = await this.fetchJson("/v2/realtime/token", {
391
+ method: "POST",
392
+ body: JSON.stringify(params),
393
+ });
394
+ return data.token;
395
+ }
396
+ }
397
+ /**
398
+ * @deprecated Use RealtimeTranscriberFactory instead
399
+ */
400
+ class RealtimeServiceFactory extends RealtimeTranscriberFactory {
401
+ }
402
+
403
+ function getPath(path) {
404
+ if (path.startsWith("http"))
405
+ return null;
406
+ if (path.startsWith("https"))
407
+ return null;
408
+ if (path.startsWith("data:"))
409
+ return null;
410
+ if (path.startsWith("file://"))
411
+ return path.substring(7);
412
+ if (path.startsWith("file:"))
413
+ return path.substring(5);
414
+ return path;
415
+ }
416
+
417
+ class TranscriptService extends BaseService {
418
+ constructor(params, files) {
419
+ super(params);
420
+ this.files = files;
421
+ }
422
+ /**
423
+ * Transcribe an audio file. This will create a transcript and wait until the transcript status is "completed" or "error".
424
+ * @param params - The parameters to transcribe an audio file.
425
+ * @param options - The options to transcribe an audio file.
426
+ * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
427
+ */
428
+ async transcribe(params, options) {
429
+ deprecateConformer2(params);
430
+ const transcript = await this.submit(params);
431
+ return await this.waitUntilReady(transcript.id, options);
432
+ }
433
+ /**
434
+ * Submits a transcription job for an audio file. This will not wait until the transcript status is "completed" or "error".
435
+ * @param params - The parameters to start the transcription of an audio file.
436
+ * @returns A promise that resolves to the queued transcript.
437
+ */
438
+ async submit(params) {
439
+ deprecateConformer2(params);
440
+ let audioUrl;
441
+ let transcriptParams = undefined;
442
+ if ("audio" in params) {
443
+ const { audio, ...audioTranscriptParams } = params;
444
+ if (typeof audio === "string") {
445
+ const path = getPath(audio);
446
+ if (path !== null) {
447
+ // audio is local path, upload local file
448
+ audioUrl = await this.files.upload(path);
449
+ }
450
+ else {
451
+ if (audio.startsWith("data:")) {
452
+ audioUrl = await this.files.upload(audio);
453
+ }
454
+ else {
455
+ // audio is not a local path, and not a data-URI, assume it's a normal URL
456
+ audioUrl = audio;
457
+ }
458
+ }
459
+ }
460
+ else {
461
+ // audio is of uploadable type
462
+ audioUrl = await this.files.upload(audio);
463
+ }
464
+ transcriptParams = { ...audioTranscriptParams, audio_url: audioUrl };
465
+ }
466
+ else {
467
+ transcriptParams = params;
468
+ }
469
+ const data = await this.fetchJson("/v2/transcript", {
470
+ method: "POST",
471
+ body: JSON.stringify(transcriptParams),
472
+ });
473
+ return data;
474
+ }
475
+ /**
476
+ * Create a transcript.
477
+ * @param params - The parameters to create a transcript.
478
+ * @param options - The options used for creating the new transcript.
479
+ * @returns A promise that resolves to the transcript.
480
+ * @deprecated Use `transcribe` instead to transcribe a audio file that includes polling, or `submit` to transcribe a audio file without polling.
481
+ */
482
+ async create(params, options) {
483
+ deprecateConformer2(params);
484
+ const path = getPath(params.audio_url);
485
+ if (path !== null) {
486
+ const uploadUrl = await this.files.upload(path);
487
+ params.audio_url = uploadUrl;
488
+ }
489
+ const data = await this.fetchJson("/v2/transcript", {
490
+ method: "POST",
491
+ body: JSON.stringify(params),
492
+ });
493
+ if (options?.poll ?? true) {
494
+ return await this.waitUntilReady(data.id, options);
495
+ }
496
+ return data;
497
+ }
498
+ /**
499
+ * Wait until the transcript ready, either the status is "completed" or "error".
500
+ * @param transcriptId - The ID of the transcript.
501
+ * @param options - The options to wait until the transcript is ready.
502
+ * @returns A promise that resolves to the transcript. The transcript status is "completed" or "error".
503
+ */
504
+ async waitUntilReady(transcriptId, options) {
505
+ const pollingInterval = options?.pollingInterval ?? 3_000;
506
+ const pollingTimeout = options?.pollingTimeout ?? -1;
507
+ const startTime = Date.now();
508
+ // eslint-disable-next-line no-constant-condition
509
+ while (true) {
510
+ const transcript = await this.get(transcriptId);
511
+ if (transcript.status === "completed" || transcript.status === "error") {
512
+ return transcript;
513
+ }
514
+ else if (pollingTimeout > 0 &&
515
+ Date.now() - startTime > pollingTimeout) {
516
+ throw new Error("Polling timeout");
517
+ }
518
+ else {
519
+ await new Promise((resolve) => setTimeout(resolve, pollingInterval));
520
+ }
521
+ }
522
+ }
523
+ /**
524
+ * Retrieve a transcript.
525
+ * @param id - The identifier of the transcript.
526
+ * @returns A promise that resolves to the transcript.
527
+ */
528
+ get(id) {
529
+ return this.fetchJson(`/v2/transcript/${id}`);
530
+ }
531
+ /**
532
+ * Retrieves a page of transcript listings.
533
+ * @param params - The parameters to filter the transcript list by, or the URL to retrieve the transcript list from.
534
+ */
535
+ async list(params) {
536
+ let url = "/v2/transcript";
537
+ if (typeof params === "string") {
538
+ url = params;
539
+ }
540
+ else if (params) {
541
+ url = `${url}?${new URLSearchParams(Object.keys(params).map((key) => [
542
+ key,
543
+ params[key]?.toString() || "",
544
+ ]))}`;
545
+ }
546
+ const data = await this.fetchJson(url);
547
+ for (const transcriptListItem of data.transcripts) {
548
+ transcriptListItem.created = new Date(transcriptListItem.created);
549
+ if (transcriptListItem.completed) {
550
+ transcriptListItem.completed = new Date(transcriptListItem.completed);
551
+ }
552
+ }
553
+ return data;
554
+ }
555
+ /**
556
+ * Delete a transcript
557
+ * @param id - The identifier of the transcript.
558
+ * @returns A promise that resolves to the transcript.
559
+ */
560
+ delete(id) {
561
+ return this.fetchJson(`/v2/transcript/${id}`, { method: "DELETE" });
562
+ }
563
+ /**
564
+ * Search through the transcript for a specific set of keywords.
565
+ * You can search for individual words, numbers, or phrases containing up to five words or numbers.
566
+ * @param id - The identifier of the transcript.
567
+ * @param words - Keywords to search for.
568
+ * @returns A promise that resolves to the sentences.
569
+ */
570
+ wordSearch(id, words) {
571
+ const params = new URLSearchParams({ words: words.join(",") });
572
+ return this.fetchJson(`/v2/transcript/${id}/word-search?${params.toString()}`);
573
+ }
574
+ /**
575
+ * Retrieve all sentences of a transcript.
576
+ * @param id - The identifier of the transcript.
577
+ * @returns A promise that resolves to the sentences.
578
+ */
579
+ sentences(id) {
580
+ return this.fetchJson(`/v2/transcript/${id}/sentences`);
581
+ }
582
+ /**
583
+ * Retrieve all paragraphs of a transcript.
584
+ * @param id - The identifier of the transcript.
585
+ * @returns A promise that resolves to the paragraphs.
586
+ */
587
+ paragraphs(id) {
588
+ return this.fetchJson(`/v2/transcript/${id}/paragraphs`);
589
+ }
590
+ /**
591
+ * Retrieve subtitles of a transcript.
592
+ * @param id - The identifier of the transcript.
593
+ * @param format - The format of the subtitles.
594
+ * @param chars_per_caption - The maximum number of characters per caption.
595
+ * @returns A promise that resolves to the subtitles text.
596
+ */
597
+ async subtitles(id, format = "srt", chars_per_caption) {
598
+ let url = `/v2/transcript/${id}/${format}`;
599
+ if (chars_per_caption) {
600
+ const params = new URLSearchParams();
601
+ params.set("chars_per_caption", chars_per_caption.toString());
602
+ url += `?${params.toString()}`;
603
+ }
604
+ const response = await this.fetch(url);
605
+ return await response.text();
606
+ }
607
+ /**
608
+ * Retrieve redactions of a transcript.
609
+ * @param id - The identifier of the transcript.
610
+ * @returns A promise that resolves to the subtitles text.
611
+ */
612
+ redactions(id) {
613
+ return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
614
+ }
615
+ }
616
+ function deprecateConformer2(params) {
617
+ if (!params)
618
+ return;
619
+ if (params.speech_model === "conformer-2") {
620
+ console.warn("The speech_model conformer-2 option is deprecated and will stop working in the near future. Use best or nano instead.");
621
+ }
622
+ }
623
+
624
+ const readFile = async function (
625
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
626
+ path) {
627
+ throw new Error("Interacting with the file system is not supported in this environment.");
628
+ };
629
+
630
+ class FileService extends BaseService {
631
+ /**
632
+ * Upload a local file to AssemblyAI.
633
+ * @param input - The local file path to upload, or a stream or buffer of the file to upload.
634
+ * @returns A promise that resolves to the uploaded file URL.
635
+ */
636
+ async upload(input) {
637
+ let fileData;
638
+ if (typeof input === "string") {
639
+ if (input.startsWith("data:")) {
640
+ fileData = dataUrlToBlob(input);
641
+ }
642
+ else {
643
+ fileData = await readFile();
644
+ }
645
+ }
646
+ else
647
+ fileData = input;
648
+ const data = await this.fetchJson("/v2/upload", {
649
+ method: "POST",
650
+ body: fileData,
651
+ headers: {
652
+ "Content-Type": "application/octet-stream",
653
+ },
654
+ duplex: "half",
655
+ });
656
+ return data.upload_url;
657
+ }
658
+ }
659
+ function dataUrlToBlob(dataUrl) {
660
+ const arr = dataUrl.split(",");
661
+ const mime = arr[0].match(/:(.*?);/)[1];
662
+ const bstr = atob(arr[1]);
663
+ let n = bstr.length;
664
+ const u8arr = new Uint8Array(n);
665
+ while (n--) {
666
+ u8arr[n] = bstr.charCodeAt(n);
667
+ }
668
+ return new Blob([u8arr], { type: mime });
669
+ }
670
+
671
+ const defaultBaseUrl = "https://api.assemblyai.com";
672
+ class AssemblyAI {
673
+ /**
674
+ * Create a new AssemblyAI client.
675
+ * @param params - The parameters for the service, including the API key and base URL, if any.
676
+ */
677
+ constructor(params) {
678
+ params.baseUrl = params.baseUrl || defaultBaseUrl;
679
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
680
+ params.baseUrl = params.baseUrl.slice(0, -1);
681
+ }
682
+ this.files = new FileService(params);
683
+ this.transcripts = new TranscriptService(params, this.files);
684
+ this.lemur = new LemurService(params);
685
+ this.realtime = new RealtimeTranscriberFactory(params);
686
+ }
687
+ }
688
+
689
+ export { AssemblyAI, FileService, LemurService, RealtimeService, RealtimeServiceFactory, RealtimeTranscriber, RealtimeTranscriberFactory, TranscriptService };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assemblyai",
3
- "version": "4.4.6",
3
+ "version": "4.4.7-beta.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"
@@ -16,7 +16,7 @@
16
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
21
  "react-native": "./dist/browser.mjs",
22
22
  "node": {
@@ -38,6 +38,10 @@
38
38
  "./package.json": "./package.json"
39
39
  },
40
40
  "imports": {
41
+ "#fetch":{
42
+ "workerd": "./src/polyfills/fetch/workerd.ts",
43
+ "default": "./src/polyfills/fetch/default.ts"
44
+ },
41
45
  "#fs": {
42
46
  "node": "./src/polyfills/fs/node.ts",
43
47
  "bun": "./src/polyfills/fs/bun.ts",
@@ -67,7 +71,7 @@
67
71
  "url": "git+https://github.com/AssemblyAI/assemblyai-node-sdk.git"
68
72
  },
69
73
  "publishConfig": {
70
- "tag": "latest",
74
+ "tag": "beta",
71
75
  "access": "public",
72
76
  "registry": "https://registry.npmjs.org/"
73
77
  },
@@ -0,0 +1,3 @@
1
+ export const DEFAULT_FETCH_INIT: Record<string, unknown> = {
2
+ cache: "no-store"
3
+ };
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_FETCH_INIT: Record<string, unknown> = {
2
+ };
@@ -1,5 +1,5 @@
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
3
  import { buildUserAgent } from "../utils/userAgent";
4
4
 
5
5
  /**
@@ -22,13 +22,13 @@ export abstract class BaseService {
22
22
  input: string,
23
23
  init?: RequestInit | undefined,
24
24
  ): Promise<Response> {
25
- init = init ?? {};
26
- let headers = init.headers ?? {};
27
- headers = {
25
+ init = { ...DEFAULT_FETCH_INIT, ...init };
26
+ let headers = {
28
27
  Authorization: this.params.apiKey,
29
28
  "Content-Type": "application/json",
30
- ...init.headers,
31
29
  };
30
+ if (DEFAULT_FETCH_INIT?.headers) headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
31
+ if (init?.headers) headers = { ...headers, ...init.headers };
32
32
 
33
33
  if (this.userAgent) {
34
34
  (headers as Record<string, string>)["User-Agent"] = this.userAgent;
@@ -40,7 +40,6 @@ export abstract class BaseService {
40
40
  }
41
41
  init.headers = headers;
42
42
 
43
- init.cache = "no-store";
44
43
  if (!input.startsWith("http")) input = this.params.baseUrl + input;
45
44
 
46
45
  const response = await fetch(input, init);