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
@@ -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,i){return new(s||(s=Promise))((function(n,o){function r(e){try{l(i.next(e))}catch(e){o(e)}}function a(e){try{l(i.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?n(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}l((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class s{constructor(e){this.params=e}fetch(e,s){return t(this,void 0,void 0,(function*(){var t;(s=null!=s?s:{}).headers=null!==(t=s.headers)&&void 0!==t?t:{},s.headers=Object.assign({Authorization:this.params.apiKey,"Content-Type":"application/json"},s.headers),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 i extends s{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:n}="undefined"!=typeof window?window:"undefined"!=typeof global?global:globalThis;var o,r;const a=null!==(r=null!==(o=null!==WebSocket&&void 0!==WebSocket?WebSocket:null===global||void 0===global?void 0:global.WebSocket)&&void 0!==o?o:null===window||void 0===window?void 0:window.WebSocket)&&void 0!==r?r:null===self||void 0===self?void 0:self.WebSocket,l=(e,t)=>t?new a(e,t):new a(e);var c;!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"}(c||(c={}));const d={[c.BadSampleRate]:"Sample rate must be a positive integer",[c.AuthFailed]:"Not Authorized",[c.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.",[c.NonexistentSessionId]:"Session ID does not exist",[c.SessionExpired]:"Session has expired",[c.ClosedSession]:"Session is closed",[c.RateLimited]:"Rate limited",[c.UniqueSessionViolation]:"Unique session violation",[c.SessionTimeout]:"Session Timeout",[c.AudioTooShort]:"Audio too short",[c.AudioTooLong]:"Audio too long",[c.BadJson]:"Bad JSON",[c.BadSchema]:"Bad schema",[c.TooManyStreams]:"Too many streams",[c.Reconnected]:"Reconnected",[c.ReconnectAttemptsExhausted]:"Reconnect attempts exhausted"};class h extends Error{}const u='{"terminate_session":true}';class p{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=l(t.toString()):this.socket=l(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,i;t||e in c&&(t=d[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,n;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(n=(i=this.listeners).error)||void 0===n||n.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,n,o,r,a,l,c,d,u,p,f,m,v,y;const S=JSON.parse(t.toString());if("error"in S)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new h(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=(n=this.listeners).open)||void 0===o||o.call(n,t);break}case"PartialTranscript":S.created=new Date(S.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,S),null===(c=(l=this.listeners)["transcript.partial"])||void 0===c||c.call(l,S);break;case"FinalTranscript":S.created=new Date(S.created),null===(u=(d=this.listeners).transcript)||void 0===u||u.call(d,S),null===(f=(p=this.listeners)["transcript.final"])||void 0===f||f.call(p,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 n({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(u),yield e}else this.socket.send(u);(null===(t=this.socket)||void 0===t?void 0:t.removeAllListeners)&&this.socket.removeAllListeners(),this.socket.close()}this.listeners={},this.socket=void 0}))}}class f extends s{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 p(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 m(e){return e.startsWith("http")||e.startsWith("https")?null:e.startsWith("file://")?e.substring(7):e.startsWith("file:")?e.substring(5):e}class v extends s{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){y(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(y(e),"audio"in e){const{audio:i}=e,n=function(e,t){var s={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(s[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(e);n<i.length;n++)t.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(s[i[n]]=e[i[n]])}return s}(e,["audio"]);if("string"==typeof i){const e=m(i);t=null!==e?yield this.files.upload(e):i}else t=yield this.files.upload(i);s=Object.assign(Object.assign({},n),{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;y(e);const i=m(e.audio_url);if(null!==i){const t=yield this.files.upload(i);e.audio_url=t}const n=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(n.id,s):n}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,i;const n=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-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,n)))}}))}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 i=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),i+=`?${e.toString()}`}const n=yield this.fetch(i);return yield n.text()}))}redactions(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}}function y(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 S extends s{upload(e){return t(this,void 0,void 0,(function*(){let s;s="string"==typeof 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 S(e),this.transcripts=new v(e,this.files),this.lemur=new i(e),this.realtime=new f(e)}},e.FileService=S,e.LemurService=i,e.RealtimeService=class extends p{},e.RealtimeServiceFactory=class extends f{},e.RealtimeTranscriber=p,e.RealtimeTranscriberFactory=f,e.TranscriptService=v}));
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,i){return new(s||(s=Promise))((function(n,o){function r(e){try{c(i.next(e))}catch(e){o(e)}}function a(e){try{c(i.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(r,a)}c((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const s={cache:"no-store"};let i="";"undefined"!=typeof navigator&&navigator.userAgent&&(i+=navigator.userAgent);const n={sdk:{name:"JavaScript",version:"4.5.0"}};"undefined"!=typeof process&&(process.versions.node&&-1===i.indexOf("Node")&&(n.runtime_env={name:"Node",version:process.versions.node}),process.versions.bun&&-1===i.indexOf("Bun")&&(n.runtime_env={name:"Bun",version:process.versions.bun})),"undefined"!=typeof Deno&&process.versions.bun&&-1===i.indexOf("Deno")&&(n.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||{},i+(!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,i){return t(this,void 0,void 0,(function*(){i=Object.assign(Object.assign({},s),i);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==i?void 0:i.headers)&&(t=Object.assign(Object.assign({},t),i.headers)),this.userAgent&&(t["User-Agent"]=this.userAgent,"undefined"!=typeof window&&"chrome"in window&&(t["AssemblyAI-Agent"]=this.userAgent)),i.headers=t,e.startsWith("http")||(e=this.params.baseUrl+e);const n=yield fetch(e,i);if(n.status>=400){let e;const t=yield n.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: ${n.status} ${n.statusText}`)}return n}))}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)})}getResponse(e){return this.fetchJson(`/lemur/v3/${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,d;const l=null!==(d=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!==d?d:null===self||void 0===self?void 0:self.WebSocket,u=(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 f={[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 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=u(t.toString()):this.socket=u(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,i;t||e in h&&(t=f[e]),null===(i=(s=this.listeners).close)||void 0===i||i.call(s,e,t)},this.socket.onerror=e=>{var t,s,i,n;e.error?null===(s=(t=this.listeners).error)||void 0===s||s.call(t,e.error):null===(n=(i=this.listeners).error)||void 0===n||n.call(i,new Error(e.message))},this.socket.onmessage=({data:t})=>{var s,i,n,o,r,a,c,d,l,u,h,f,m,v,y;const b=JSON.parse(t.toString());if("error"in b)null===(i=(s=this.listeners).error)||void 0===i||i.call(s,new p(b.error));else switch(b.message_type){case"SessionBegins":{const t={sessionId:b.session_id,expiresAt:new Date(b.expires_at)};e(t),null===(o=(n=this.listeners).open)||void 0===o||o.call(n,t);break}case"PartialTranscript":b.created=new Date(b.created),null===(a=(r=this.listeners).transcript)||void 0===a||a.call(r,b),null===(d=(c=this.listeners)["transcript.partial"])||void 0===d||d.call(c,b);break;case"FinalTranscript":b.created=new Date(b.created),null===(u=(l=this.listeners).transcript)||void 0===u||u.call(l,b),null===(f=(h=this.listeners)["transcript.final"])||void 0===f||f.call(h,b);break;case"SessionInformation":null===(v=(m=this.listeners).session_information)||void 0===v||v.call(m,b);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 b(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 o{constructor(e,t){super(e),this.files=t}transcribe(e,s){return t(this,void 0,void 0,(function*(){g(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(g(e),"audio"in e){const{audio:i}=e,n=function(e,t){var s={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(s[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(e);n<i.length;n++)t.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(s[i[n]]=e[i[n]])}return s}(e,["audio"]);if("string"==typeof i){const e=b(i);t=null!==e?yield this.files.upload(e):i.startsWith("data:")?yield this.files.upload(i):i}else t=yield this.files.upload(i);s=Object.assign(Object.assign({},n),{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;g(e);const i=b(e.audio_url);if(null!==i){const t=yield this.files.upload(i);e.audio_url=t}const n=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(n.id,s):n}))}waitUntilReady(e,s){return t(this,void 0,void 0,(function*(){var t,i;const n=null!==(t=null==s?void 0:s.pollingInterval)&&void 0!==t?t:3e3,o=null!==(i=null==s?void 0:s.pollingTimeout)&&void 0!==i?i:-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,n)))}}))}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 i=`/v2/transcript/${e}/${t}`;if(s){const e=new URLSearchParams;e.set("chars_per_caption",s.toString()),i+=`?${e.toString()}`}const n=yield this.fetch(i);return yield n.text()}))}redactions(e){return this.redactedAudio(e)}redactedAudio(e){return this.fetchJson(`/v2/transcript/${e}/redacted-audio`)}redactedAudioFile(e){return t(this,void 0,void 0,(function*(){const{redacted_audio_url:t,status:s}=yield this.redactedAudio(e);if("redacted_audio_ready"!==s)throw new Error(`Redacted audio status is ${s}`);const i=yield fetch(t);if(!i.ok)throw new Error(`Failed to fetch redacted audio: ${i.statusText}`);return{arrayBuffer:i.arrayBuffer.bind(i),blob:i.blob.bind(i),body:i.body,bodyUsed:i.bodyUsed}}))}}function g(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],i=atob(t[1]);let n=i.length;const o=new Uint8Array(n);for(;n--;)o[n]=i.charCodeAt(n);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 S(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=S}));
package/dist/browser.mjs CHANGED
@@ -1,3 +1,42 @@
1
+ const DEFAULT_FETCH_INIT = {
2
+ cache: "no-store",
3
+ };
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.5.0" },
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
+
1
40
  /**
2
41
  * Base class for services that communicate with the API.
3
42
  */
@@ -8,15 +47,32 @@ class BaseService {
8
47
  */
9
48
  constructor(params) {
10
49
  this.params = params;
50
+ if (params.userAgent === false) {
51
+ this.userAgent = undefined;
52
+ }
53
+ else {
54
+ this.userAgent = buildUserAgent(params.userAgent || {});
55
+ }
11
56
  }
12
57
  async fetch(input, init) {
13
- init = init ?? {};
14
- init.headers = init.headers ?? {};
15
- init.headers = {
58
+ init = { ...DEFAULT_FETCH_INIT, ...init };
59
+ let headers = {
16
60
  Authorization: this.params.apiKey,
17
61
  "Content-Type": "application/json",
18
- ...init.headers,
19
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;
20
76
  if (!input.startsWith("http"))
21
77
  input = this.params.baseUrl + input;
22
78
  const response = await fetch(input, init);
@@ -69,6 +125,9 @@ class LemurService extends BaseService {
69
125
  body: JSON.stringify(params),
70
126
  });
71
127
  }
128
+ getResponse(id) {
129
+ return this.fetchJson(`/lemur/v3/${id}`);
130
+ }
72
131
  /**
73
132
  * Delete the data for a previously submitted LeMUR request.
74
133
  * @param id - ID of the LeMUR request
@@ -355,6 +414,8 @@ function getPath(path) {
355
414
  return null;
356
415
  if (path.startsWith("https"))
357
416
  return null;
417
+ if (path.startsWith("data:"))
418
+ return null;
358
419
  if (path.startsWith("file://"))
359
420
  return path.substring(7);
360
421
  if (path.startsWith("file:"))
@@ -396,8 +457,13 @@ class TranscriptService extends BaseService {
396
457
  audioUrl = await this.files.upload(path);
397
458
  }
398
459
  else {
399
- // audio is not a local path, assume it's a URL
400
- audioUrl = audio;
460
+ if (audio.startsWith("data:")) {
461
+ audioUrl = await this.files.upload(audio);
462
+ }
463
+ else {
464
+ // audio is not a local path, and not a data-URI, assume it's a normal URL
465
+ audioUrl = audio;
466
+ }
401
467
  }
402
468
  }
403
469
  else {
@@ -548,13 +614,43 @@ class TranscriptService extends BaseService {
548
614
  return await response.text();
549
615
  }
550
616
  /**
551
- * Retrieve redactions of a transcript.
617
+ * Retrieve the redacted audio URL of a transcript.
552
618
  * @param id - The identifier of the transcript.
553
- * @returns A promise that resolves to the subtitles text.
619
+ * @returns A promise that resolves to the details of the redacted audio.
620
+ * @deprecated Use `redactedAudio` instead.
554
621
  */
555
622
  redactions(id) {
623
+ return this.redactedAudio(id);
624
+ }
625
+ /**
626
+ * Retrieve the redacted audio URL of a transcript.
627
+ * @param id - The identifier of the transcript.
628
+ * @returns A promise that resolves to the details of the redacted audio.
629
+ */
630
+ redactedAudio(id) {
556
631
  return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
557
632
  }
633
+ /**
634
+ * Retrieve the redacted audio file of a transcript.
635
+ * @param id - The identifier of the transcript.
636
+ * @returns A promise that resolves to the fetch HTTP response of the redacted audio file.
637
+ */
638
+ async redactedAudioFile(id) {
639
+ const { redacted_audio_url, status } = await this.redactedAudio(id);
640
+ if (status !== "redacted_audio_ready") {
641
+ throw new Error(`Redacted audio status is ${status}`);
642
+ }
643
+ const response = await fetch(redacted_audio_url);
644
+ if (!response.ok) {
645
+ throw new Error(`Failed to fetch redacted audio: ${response.statusText}`);
646
+ }
647
+ return {
648
+ arrayBuffer: response.arrayBuffer.bind(response),
649
+ blob: response.blob.bind(response),
650
+ body: response.body,
651
+ bodyUsed: response.bodyUsed,
652
+ };
653
+ }
558
654
  }
559
655
  function deprecateConformer2(params) {
560
656
  if (!params)
@@ -578,8 +674,14 @@ class FileService extends BaseService {
578
674
  */
579
675
  async upload(input) {
580
676
  let fileData;
581
- if (typeof input === "string")
582
- fileData = await readFile();
677
+ if (typeof input === "string") {
678
+ if (input.startsWith("data:")) {
679
+ fileData = dataUrlToBlob(input);
680
+ }
681
+ else {
682
+ fileData = await readFile();
683
+ }
684
+ }
583
685
  else
584
686
  fileData = input;
585
687
  const data = await this.fetchJson("/v2/upload", {
@@ -593,6 +695,17 @@ class FileService extends BaseService {
593
695
  return data.upload_url;
594
696
  }
595
697
  }
698
+ function dataUrlToBlob(dataUrl) {
699
+ const arr = dataUrl.split(",");
700
+ const mime = arr[0].match(/:(.*?);/)[1];
701
+ const bstr = atob(arr[1]);
702
+ let n = bstr.length;
703
+ const u8arr = new Uint8Array(n);
704
+ while (n--) {
705
+ u8arr[n] = bstr.charCodeAt(n);
706
+ }
707
+ return new Blob([u8arr], { type: mime });
708
+ }
596
709
 
597
710
  const defaultBaseUrl = "https://api.assemblyai.com";
598
711
  class AssemblyAI {
@@ -602,8 +715,9 @@ class AssemblyAI {
602
715
  */
603
716
  constructor(params) {
604
717
  params.baseUrl = params.baseUrl || defaultBaseUrl;
605
- if (params.baseUrl && params.baseUrl.endsWith("/"))
718
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
606
719
  params.baseUrl = params.baseUrl.slice(0, -1);
720
+ }
607
721
  this.files = new FileService(params);
608
722
  this.transcripts = new TranscriptService(params, this.files);
609
723
  this.lemur = new LemurService(params);
package/dist/bun.mjs CHANGED
@@ -1,5 +1,44 @@
1
1
  import ws from 'ws';
2
2
 
3
+ const DEFAULT_FETCH_INIT = {
4
+ cache: "no-store",
5
+ };
6
+
7
+ const buildUserAgent = (userAgent) => defaultUserAgentString +
8
+ (userAgent === false
9
+ ? ""
10
+ : " AssemblyAI/1.0 (" +
11
+ Object.entries({ ...defaultUserAgent, ...userAgent })
12
+ .map(([key, item]) => item ? `${key}=${item.name}/${item.version}` : "")
13
+ .join(" ") +
14
+ ")");
15
+ let defaultUserAgentString = "";
16
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
17
+ defaultUserAgentString += navigator.userAgent;
18
+ }
19
+ const defaultUserAgent = {
20
+ sdk: { name: "JavaScript", version: "4.5.0" },
21
+ };
22
+ if (typeof process !== "undefined") {
23
+ if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
24
+ defaultUserAgent.runtime_env = {
25
+ name: "Node",
26
+ version: process.versions.node,
27
+ };
28
+ }
29
+ if (process.versions.bun && defaultUserAgentString.indexOf("Bun") === -1) {
30
+ defaultUserAgent.runtime_env = {
31
+ name: "Bun",
32
+ version: process.versions.bun,
33
+ };
34
+ }
35
+ }
36
+ if (typeof Deno !== "undefined") {
37
+ if (process.versions.bun && defaultUserAgentString.indexOf("Deno") === -1) {
38
+ defaultUserAgent.runtime_env = { name: "Deno", version: Deno.version.deno };
39
+ }
40
+ }
41
+
3
42
  /**
4
43
  * Base class for services that communicate with the API.
5
44
  */
@@ -10,15 +49,32 @@ class BaseService {
10
49
  */
11
50
  constructor(params) {
12
51
  this.params = params;
52
+ if (params.userAgent === false) {
53
+ this.userAgent = undefined;
54
+ }
55
+ else {
56
+ this.userAgent = buildUserAgent(params.userAgent || {});
57
+ }
13
58
  }
14
59
  async fetch(input, init) {
15
- init = init ?? {};
16
- init.headers = init.headers ?? {};
17
- init.headers = {
60
+ init = { ...DEFAULT_FETCH_INIT, ...init };
61
+ let headers = {
18
62
  Authorization: this.params.apiKey,
19
63
  "Content-Type": "application/json",
20
- ...init.headers,
21
64
  };
65
+ if (DEFAULT_FETCH_INIT?.headers)
66
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
67
+ if (init?.headers)
68
+ headers = { ...headers, ...init.headers };
69
+ if (this.userAgent) {
70
+ headers["User-Agent"] = this.userAgent;
71
+ // chromium browsers have a bug where the user agent can't be modified
72
+ if (typeof window !== "undefined" && "chrome" in window) {
73
+ headers["AssemblyAI-Agent"] =
74
+ this.userAgent;
75
+ }
76
+ }
77
+ init.headers = headers;
22
78
  if (!input.startsWith("http"))
23
79
  input = this.params.baseUrl + input;
24
80
  const response = await fetch(input, init);
@@ -71,6 +127,9 @@ class LemurService extends BaseService {
71
127
  body: JSON.stringify(params),
72
128
  });
73
129
  }
130
+ getResponse(id) {
131
+ return this.fetchJson(`/lemur/v3/${id}`);
132
+ }
74
133
  /**
75
134
  * Delete the data for a previously submitted LeMUR request.
76
135
  * @param id - ID of the LeMUR request
@@ -351,6 +410,8 @@ function getPath(path) {
351
410
  return null;
352
411
  if (path.startsWith("https"))
353
412
  return null;
413
+ if (path.startsWith("data:"))
414
+ return null;
354
415
  if (path.startsWith("file://"))
355
416
  return path.substring(7);
356
417
  if (path.startsWith("file:"))
@@ -392,8 +453,13 @@ class TranscriptService extends BaseService {
392
453
  audioUrl = await this.files.upload(path);
393
454
  }
394
455
  else {
395
- // audio is not a local path, assume it's a URL
396
- audioUrl = audio;
456
+ if (audio.startsWith("data:")) {
457
+ audioUrl = await this.files.upload(audio);
458
+ }
459
+ else {
460
+ // audio is not a local path, and not a data-URI, assume it's a normal URL
461
+ audioUrl = audio;
462
+ }
397
463
  }
398
464
  }
399
465
  else {
@@ -544,13 +610,43 @@ class TranscriptService extends BaseService {
544
610
  return await response.text();
545
611
  }
546
612
  /**
547
- * Retrieve redactions of a transcript.
613
+ * Retrieve the redacted audio URL of a transcript.
548
614
  * @param id - The identifier of the transcript.
549
- * @returns A promise that resolves to the subtitles text.
615
+ * @returns A promise that resolves to the details of the redacted audio.
616
+ * @deprecated Use `redactedAudio` instead.
550
617
  */
551
618
  redactions(id) {
619
+ return this.redactedAudio(id);
620
+ }
621
+ /**
622
+ * Retrieve the redacted audio URL of a transcript.
623
+ * @param id - The identifier of the transcript.
624
+ * @returns A promise that resolves to the details of the redacted audio.
625
+ */
626
+ redactedAudio(id) {
552
627
  return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
553
628
  }
629
+ /**
630
+ * Retrieve the redacted audio file of a transcript.
631
+ * @param id - The identifier of the transcript.
632
+ * @returns A promise that resolves to the fetch HTTP response of the redacted audio file.
633
+ */
634
+ async redactedAudioFile(id) {
635
+ const { redacted_audio_url, status } = await this.redactedAudio(id);
636
+ if (status !== "redacted_audio_ready") {
637
+ throw new Error(`Redacted audio status is ${status}`);
638
+ }
639
+ const response = await fetch(redacted_audio_url);
640
+ if (!response.ok) {
641
+ throw new Error(`Failed to fetch redacted audio: ${response.statusText}`);
642
+ }
643
+ return {
644
+ arrayBuffer: response.arrayBuffer.bind(response),
645
+ blob: response.blob.bind(response),
646
+ body: response.body,
647
+ bodyUsed: response.bodyUsed,
648
+ };
649
+ }
554
650
  }
555
651
  function deprecateConformer2(params) {
556
652
  if (!params)
@@ -570,8 +666,14 @@ class FileService extends BaseService {
570
666
  */
571
667
  async upload(input) {
572
668
  let fileData;
573
- if (typeof input === "string")
574
- fileData = await readFile(input);
669
+ if (typeof input === "string") {
670
+ if (input.startsWith("data:")) {
671
+ fileData = dataUrlToBlob(input);
672
+ }
673
+ else {
674
+ fileData = await readFile(input);
675
+ }
676
+ }
575
677
  else
576
678
  fileData = input;
577
679
  const data = await this.fetchJson("/v2/upload", {
@@ -585,6 +687,17 @@ class FileService extends BaseService {
585
687
  return data.upload_url;
586
688
  }
587
689
  }
690
+ function dataUrlToBlob(dataUrl) {
691
+ const arr = dataUrl.split(",");
692
+ const mime = arr[0].match(/:(.*?);/)[1];
693
+ const bstr = atob(arr[1]);
694
+ let n = bstr.length;
695
+ const u8arr = new Uint8Array(n);
696
+ while (n--) {
697
+ u8arr[n] = bstr.charCodeAt(n);
698
+ }
699
+ return new Blob([u8arr], { type: mime });
700
+ }
588
701
 
589
702
  const defaultBaseUrl = "https://api.assemblyai.com";
590
703
  class AssemblyAI {
@@ -594,8 +707,9 @@ class AssemblyAI {
594
707
  */
595
708
  constructor(params) {
596
709
  params.baseUrl = params.baseUrl || defaultBaseUrl;
597
- if (params.baseUrl && params.baseUrl.endsWith("/"))
710
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
598
711
  params.baseUrl = params.baseUrl.slice(0, -1);
712
+ }
599
713
  this.files = new FileService(params);
600
714
  this.transcripts = new TranscriptService(params, this.files);
601
715
  this.lemur = new LemurService(params);
package/dist/deno.mjs CHANGED
@@ -1,5 +1,44 @@
1
1
  import ws from 'ws';
2
2
 
3
+ const DEFAULT_FETCH_INIT = {
4
+ cache: "no-store",
5
+ };
6
+
7
+ const buildUserAgent = (userAgent) => defaultUserAgentString +
8
+ (userAgent === false
9
+ ? ""
10
+ : " AssemblyAI/1.0 (" +
11
+ Object.entries({ ...defaultUserAgent, ...userAgent })
12
+ .map(([key, item]) => item ? `${key}=${item.name}/${item.version}` : "")
13
+ .join(" ") +
14
+ ")");
15
+ let defaultUserAgentString = "";
16
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
17
+ defaultUserAgentString += navigator.userAgent;
18
+ }
19
+ const defaultUserAgent = {
20
+ sdk: { name: "JavaScript", version: "4.5.0" },
21
+ };
22
+ if (typeof process !== "undefined") {
23
+ if (process.versions.node && defaultUserAgentString.indexOf("Node") === -1) {
24
+ defaultUserAgent.runtime_env = {
25
+ name: "Node",
26
+ version: process.versions.node,
27
+ };
28
+ }
29
+ if (process.versions.bun && defaultUserAgentString.indexOf("Bun") === -1) {
30
+ defaultUserAgent.runtime_env = {
31
+ name: "Bun",
32
+ version: process.versions.bun,
33
+ };
34
+ }
35
+ }
36
+ if (typeof Deno !== "undefined") {
37
+ if (process.versions.bun && defaultUserAgentString.indexOf("Deno") === -1) {
38
+ defaultUserAgent.runtime_env = { name: "Deno", version: Deno.version.deno };
39
+ }
40
+ }
41
+
3
42
  /**
4
43
  * Base class for services that communicate with the API.
5
44
  */
@@ -10,15 +49,32 @@ class BaseService {
10
49
  */
11
50
  constructor(params) {
12
51
  this.params = params;
52
+ if (params.userAgent === false) {
53
+ this.userAgent = undefined;
54
+ }
55
+ else {
56
+ this.userAgent = buildUserAgent(params.userAgent || {});
57
+ }
13
58
  }
14
59
  async fetch(input, init) {
15
- init = init ?? {};
16
- init.headers = init.headers ?? {};
17
- init.headers = {
60
+ init = { ...DEFAULT_FETCH_INIT, ...init };
61
+ let headers = {
18
62
  Authorization: this.params.apiKey,
19
63
  "Content-Type": "application/json",
20
- ...init.headers,
21
64
  };
65
+ if (DEFAULT_FETCH_INIT?.headers)
66
+ headers = { ...headers, ...DEFAULT_FETCH_INIT.headers };
67
+ if (init?.headers)
68
+ headers = { ...headers, ...init.headers };
69
+ if (this.userAgent) {
70
+ headers["User-Agent"] = this.userAgent;
71
+ // chromium browsers have a bug where the user agent can't be modified
72
+ if (typeof window !== "undefined" && "chrome" in window) {
73
+ headers["AssemblyAI-Agent"] =
74
+ this.userAgent;
75
+ }
76
+ }
77
+ init.headers = headers;
22
78
  if (!input.startsWith("http"))
23
79
  input = this.params.baseUrl + input;
24
80
  const response = await fetch(input, init);
@@ -71,6 +127,9 @@ class LemurService extends BaseService {
71
127
  body: JSON.stringify(params),
72
128
  });
73
129
  }
130
+ getResponse(id) {
131
+ return this.fetchJson(`/lemur/v3/${id}`);
132
+ }
74
133
  /**
75
134
  * Delete the data for a previously submitted LeMUR request.
76
135
  * @param id - ID of the LeMUR request
@@ -351,6 +410,8 @@ function getPath(path) {
351
410
  return null;
352
411
  if (path.startsWith("https"))
353
412
  return null;
413
+ if (path.startsWith("data:"))
414
+ return null;
354
415
  if (path.startsWith("file://"))
355
416
  return path.substring(7);
356
417
  if (path.startsWith("file:"))
@@ -392,8 +453,13 @@ class TranscriptService extends BaseService {
392
453
  audioUrl = await this.files.upload(path);
393
454
  }
394
455
  else {
395
- // audio is not a local path, assume it's a URL
396
- audioUrl = audio;
456
+ if (audio.startsWith("data:")) {
457
+ audioUrl = await this.files.upload(audio);
458
+ }
459
+ else {
460
+ // audio is not a local path, and not a data-URI, assume it's a normal URL
461
+ audioUrl = audio;
462
+ }
397
463
  }
398
464
  }
399
465
  else {
@@ -544,13 +610,43 @@ class TranscriptService extends BaseService {
544
610
  return await response.text();
545
611
  }
546
612
  /**
547
- * Retrieve redactions of a transcript.
613
+ * Retrieve the redacted audio URL of a transcript.
548
614
  * @param id - The identifier of the transcript.
549
- * @returns A promise that resolves to the subtitles text.
615
+ * @returns A promise that resolves to the details of the redacted audio.
616
+ * @deprecated Use `redactedAudio` instead.
550
617
  */
551
618
  redactions(id) {
619
+ return this.redactedAudio(id);
620
+ }
621
+ /**
622
+ * Retrieve the redacted audio URL of a transcript.
623
+ * @param id - The identifier of the transcript.
624
+ * @returns A promise that resolves to the details of the redacted audio.
625
+ */
626
+ redactedAudio(id) {
552
627
  return this.fetchJson(`/v2/transcript/${id}/redacted-audio`);
553
628
  }
629
+ /**
630
+ * Retrieve the redacted audio file of a transcript.
631
+ * @param id - The identifier of the transcript.
632
+ * @returns A promise that resolves to the fetch HTTP response of the redacted audio file.
633
+ */
634
+ async redactedAudioFile(id) {
635
+ const { redacted_audio_url, status } = await this.redactedAudio(id);
636
+ if (status !== "redacted_audio_ready") {
637
+ throw new Error(`Redacted audio status is ${status}`);
638
+ }
639
+ const response = await fetch(redacted_audio_url);
640
+ if (!response.ok) {
641
+ throw new Error(`Failed to fetch redacted audio: ${response.statusText}`);
642
+ }
643
+ return {
644
+ arrayBuffer: response.arrayBuffer.bind(response),
645
+ blob: response.blob.bind(response),
646
+ body: response.body,
647
+ bodyUsed: response.bodyUsed,
648
+ };
649
+ }
554
650
  }
555
651
  function deprecateConformer2(params) {
556
652
  if (!params)
@@ -570,8 +666,14 @@ class FileService extends BaseService {
570
666
  */
571
667
  async upload(input) {
572
668
  let fileData;
573
- if (typeof input === "string")
574
- fileData = await readFile(input);
669
+ if (typeof input === "string") {
670
+ if (input.startsWith("data:")) {
671
+ fileData = dataUrlToBlob(input);
672
+ }
673
+ else {
674
+ fileData = await readFile(input);
675
+ }
676
+ }
575
677
  else
576
678
  fileData = input;
577
679
  const data = await this.fetchJson("/v2/upload", {
@@ -585,6 +687,17 @@ class FileService extends BaseService {
585
687
  return data.upload_url;
586
688
  }
587
689
  }
690
+ function dataUrlToBlob(dataUrl) {
691
+ const arr = dataUrl.split(",");
692
+ const mime = arr[0].match(/:(.*?);/)[1];
693
+ const bstr = atob(arr[1]);
694
+ let n = bstr.length;
695
+ const u8arr = new Uint8Array(n);
696
+ while (n--) {
697
+ u8arr[n] = bstr.charCodeAt(n);
698
+ }
699
+ return new Blob([u8arr], { type: mime });
700
+ }
588
701
 
589
702
  const defaultBaseUrl = "https://api.assemblyai.com";
590
703
  class AssemblyAI {
@@ -594,8 +707,9 @@ class AssemblyAI {
594
707
  */
595
708
  constructor(params) {
596
709
  params.baseUrl = params.baseUrl || defaultBaseUrl;
597
- if (params.baseUrl && params.baseUrl.endsWith("/"))
710
+ if (params.baseUrl && params.baseUrl.endsWith("/")) {
598
711
  params.baseUrl = params.baseUrl.slice(0, -1);
712
+ }
599
713
  this.files = new FileService(params);
600
714
  this.transcripts = new TranscriptService(params, this.files);
601
715
  this.lemur = new LemurService(params);