speechmatics / speechmatics-js-sdk

Javascript and Typescript SDK for Speechmatics
MIT License
39 stars 4 forks source link

Failed npm run dev for microphone nextjs example #24

Closed yuriigeivakh closed 8 months ago

yuriigeivakh commented 8 months ago

Describe the bug Not able to launch one of the demo example

To Reproduce Steps to reproduce the behavior:

  1. Go to '...'
  2. Run npm run dev

Node and npm version node v14.17.5 npm 6.14.14

Log -1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];{throw new C("Invalid URL pathname: the pathname must be a string or null/undefined.")}if(A.hostname!=null&&typeof A.hostname!=="string"){throw new C("Invalid URL hostname: the hostname must be a string or null/undefined.")}if(A.origin!=null&&typeof A.origin!=="string"){throw new C("Invalid URL origin: the origin must be a string or null/undefined.")}if(!/^https?:/.test(A.origin||A.protocol)){throw new C("Invalid URL protocol: the URL must start withhttp:orhttps:.")}if(!(A instanceof URL)){const e=A.port!=null?A.port:A.protocol==="https:"?443:80;let t=A.origin!=null?A.origin:${A.protocol}//${A.hostname}:${e};let s=A.path!=null?A.path:${A.pathname||""}${A.search||""};if(t.endsWith("/")){t=t.substring(0,t.length-1)}if(s&&!s.startsWith("/")){s=/${s}}A=new URL(t+s)}return A}function parseOrigin(A){A=parseURL(A);if(A.pathname!=="/"||A.search||A.hash){throw new C("invalid url")}return A}function getHostname(A){if(A[0]==="["){const e=A.indexOf("]");s(e!==-1);return A.substr(1,e-1)}const e=A.indexOf(":");if(e===-1)return A;return A.substr(0,e)}function getServerName(A){if(!A){return null}s.strictEqual(typeof A,"string");const e=getHostname(A);if(g.isIP(e)){return""}return e}function deepClone(A){return JSON.parse(JSON.stringify(A))}function isAsyncIterable(A){return!!(A!=null&&typeof A[Symbol.asyncIterator]==="function")}function isIterable(A){return!!(A!=null&&(typeof A[Symbol.iterator]==="function"||typeof A[Symbol.asyncIterator]==="function"))}function bodyLength(A){if(A==null){return 0}else if(isStream(A)){const e=A._readableState;return e&&e.ended===true&&Number.isFinite(e.length)?e.length:null}else if(isBlobLike(A)){return A.size!=null?A.size:null}else if(isBuffer(A)){return A.byteLength}return null}function isDestroyed(A){return!A||!!(A.destroyed||A[o])}function isReadableAborted(A){const e=A&&A._readableState;return isDestroyed(A)&&e&&!e.endEmitted}function destroy(A,e){if(!isStream(A)||isDestroyed(A)){return}if(typeof A.destroy==="function"){if(Object.getPrototypeOf(A).constructor===i){A.socket=null}A.destroy(e)}else if(e){process.nextTick(((A,e)=>{A.emit("error",e)}),A,e)}if(A.destroyed!==true){A[o]=true}}const c=/timeout=(\d+)/;function parseKeepAliveTimeout(A){const e=A.toString().match(c);return e?parseInt(e[1],10)*1e3:null}function parseHeaders(A,e={}){for(let t=0;t<A.length;t+=2){const s=A[t].toString().toLowerCase();let o=e[s];if(!o){if(Array.isArray(A[t+1])){e[s]=A[t+1]}else{e[s]=A[t+1].toString("utf8")}}else{if(!Array.isArray(o)){o=[o];e[s]=o}o.push(A[t+1].toString("utf8"))}}if("content-length"in e&&"content-disposition"in e){e["content-disposition"]=Buffer.from(e["content-disposition"]).toString("latin1")}return e}function parseRawHeaders(A){const e=[];let t=false;let s=-1;for(let o=0;o<A.length;o+=2){const r=A[o+0].toString();const i=A[o+1].toString("utf8");if(r.length===14&&(r==="content-length"||r.toLowerCase()==="content-length")){e.push(r,i);t=true}else if(r.length===19&&(r==="content-disposition"||r.toLowerCase()==="content-disposition")){s=e.push(r,i)-1}else{e.push(r,i)}}if(t&&s!==-1){e[s]=Buffer.from(e[s]).toString("latin1")}return e}function isBuffer(A){return A instanceof Uint8Array||Buffer.isBuffer(A)}function validateHandler(A,e,t){if(!A||typeof A!=="object"){throw new C("handler must be an object")}if(typeof A.onConnect!=="function"){throw new C("invalid onConnect method")}if(typeof A.onError!=="function"){throw new C("invalid onError method")}if(typeof A.onBodySent!=="function"&&A.onBodySent!==undefined){throw new C("invalid onBodySent method")}if(t||e==="CONNECT"){if(typeof A.onUpgrade!=="function"){throw new C("invalid onUpgrade method")}}else{if(typeof A.onHeaders!=="function"){throw new C("invalid onHeaders method")}if(typeof A.onData!=="function"){throw new C("invalid onData method")}if(typeof A.onComplete!=="function"){throw new C("invalid onComplete method")}}}function isDisturbed(A){return!!(A&&(n.isDisturbed?n.isDisturbed(A)||A[r]:A[r]||A.readableDidRead||A._readableState&&A._readableState.dataEmitted||isReadableAborted(A)))}function isErrored(A){return!!(A&&(n.isErrored?n.isErrored(A):/state: 'errored'/.test(Q.inspect(A))))}function isReadable(A){return!!(A&&(n.isReadable?n.isReadable(A):/state: 'readable'/.test(Q.inspect(A))))}function getSocketInfo(A){return{localAddress:A.localAddress,localPort:A.localPort,remoteAddress:A.remoteAddress,remotePort:A.remotePort,remoteFamily:A.remoteFamily,timeout:A.timeout,bytesWritten:A.bytesWritten,bytesRead:A.bytesRead}}let h;function ReadableStreamFrom(A){if(!h){h=t(5356).ReadableStream}if(h.from){return h.from(A)}let e;return new h({async start(){e=A[Symbol.asyncIterator]()},async pull(A){const{done:t,value:s}=await e.next();if(t){queueMicrotask((()=>{A.close()}))}else{const e=Buffer.isBuffer(s)?s:Buffer.from(s);A.enqueue(new Uint8Array(e))}return A.desiredSize>0},async cancel(A){await e.return()}},0)}function isFormDataLike(A){return A&&typeof A==="object"&&typeof A.append==="function"&&typeof A.delete==="function"&&typeof A.get==="function"&&typeof A.getAll==="function"&&typeof A.has==="function"&&typeof A.set==="function"&&A[Symbol.toStringTag]==="FormData"}function throwIfAborted(A){if(!A){return}if(typeof A.throwIfAborted==="function"){A.throwIfAborted()}else{if(A.aborted){const A=new Error("The operation was aborted");A.name="AbortError";throw A}}}const l=!!String.prototype.toWellFormed;function toUSVString(A){if(l){return${A}.toWellFormed()}else if(Q.toUSVString){return Q.toUSVString(A)}return${A}}const u=Object.create(null);u.enumerable=true;A.exports={kEnumerableProperty:u,nop:nop,isDisturbed:isDisturbed,isErrored:isErrored,isReadable:isReadable,toUSVString:toUSVString,isReadableAborted:isReadableAborted,isBlobLike:isBlobLike,parseOrigin:parseOrigin,parseURL:parseURL,getServerName:getServerName,isStream:isStream,isIterable:isIterable,isAsyncIterable:isAsyncIterable,isDestroyed:isDestroyed,parseRawHeaders:parseRawHeaders,parseHeaders:parseHeaders,parseKeepAliveTimeout:parseKeepAliveTimeout,destroy:destroy,bodyLength:bodyLength,deepClone:deepClone,ReadableStreamFrom:ReadableStreamFrom,isBuffer:isBuffer,validateHandler:validateHandler,getSocketInfo:getSocketInfo,isFormDataLike:isFormDataLike,buildURL:buildURL,throwIfAborted:throwIfAborted,nodeMajor:B,nodeMinor:a,nodeHasAutoSelectFamily:B>18||B===18&&a>=13}},9291:(A,e,t)=>{"use strict";const s=t(5456);const{ClientDestroyedError:o,ClientClosedError:r,InvalidArgumentError:i}=t(223);const{kDestroy:n,kClose:g,kDispatch:C,kInterceptors:E}=t(2270);const Q=Symbol("destroyed");const I=Symbol("closed");const B=Symbol("onDestroyed");const a=Symbol("onClosed");const c=Symbol("Intercepted Dispatch");class DispatcherBase extends s{constructor(){super();this[Q]=false;this[B]=null;this[I]=false;this[a]=[]}get destroyed(){return this[Q]}get closed(){return this[I]}get interceptors(){return this[E]}set interceptors(A){if(A){for(let e=A.length-1;e>=0;e--){const A=this[E][e];if(typeof A!=="function"){throw new i("interceptor must be an function")}}}this[E]=A}close(A){if(A===undefined){return new Promise(((A,e)=>{this.close(((t,s)=>t?e(t):A(s)))}))}if(typeof A!=="function"){throw new i("invalid callback")}if(this[Q]){queueMicrotask((()=>A(new o,null)));return}if(this[I]){if(this[a]){this[a].push(A)}else{queueMicrotask((()=>A(null,null)))}return}this[I]=true;this[a].push(A);const onClosed=()=>{const A=this[a];this[a]=null;for(let e=0;e<A.length;e++){A[e](null,null)}};this[g]().then((()=>this.destroy())).then((()=>{queueMicrotask(onClosed)}))}destroy(A,e){if(typeof A==="function"){e=A;A=null}if(e===undefined){return new Promise(((e,t)=>{this.destroy(A,((A,s)=>A?t(A):e(s)))}))}if(typeof e!=="function"){throw new i("invalid callback")}if(this[Q]){if(this[B]){this[B].push(e)}else{queueMicrotask((()=>e(null,null)))}return}if(!A){A=new o}this[Q]=true;this[B]=this[B]||[];this[B].push(e);const onDestroyed=()=>{const A=this[B];this[B]=null;for(let e=0;e<A.length;e++){A[e](null,null)}};this[n](A).then((()=>{queueMicrotask(onDestroyed)}))}[c](A,e){if(!this[E]||this[E].length===0){this[c]=this[C];return this[C](A,e)}let t=this[C].bind(this);for(let A=this[E].length-1;A>=0;A--){t=this[E][A](t)}this[c]=t;return t(A,e)}dispatch(A,e){if(!e||typeof e!=="object"){throw new i("handler must be an object")}try{if(!A||typeof A!=="object"){throw new i("opts must be an object.")}if(this[Q]||this[B]){throw new o}if(this[I]){throw new r}return this[c](A,e)}catch(A){if(typeof e.onError!=="function"){throw new i("invalid onError method")}e.onError(A);return false}}}A.exports=DispatcherBase},5456:(A,e,t)=>{"use strict";const s=t(2361);class Dispatcher extends s{dispatch(){throw new Error("not implemented")}close(){throw new Error("not implemented")}destroy(){throw new Error("not implemented")}}A.exports=Dispatcher},7781:(A,e,t)=>{"use strict";const s=t(1900);const o=t(1957);const{ReadableStreamFrom:r,isBlobLike:i,isReadableStreamLike:n,readableStreamClose:g,createDeferredPromise:C,fullyReadBody:E}=t(9343);const{FormData:Q}=t(131);const{kState:I}=t(3859);const{webidl:B}=t(8017);const{DOMException:a,structuredClone:c}=t(262);const{Blob:h,File:l}=t(4300);const{kBodyUsed:u}=t(2270);const d=t(9491);const{isErrored:f}=t(1957);const{isUint8Array:y,isArrayBuffer:D}=t(5368);const{File:k}=t(4100);const{parseMIMEType:w,serializeAMimeType:S}=t(8790);let p=globalThis.ReadableStream;const N=l??k;function extractBody(A,e=false){if(!p){p=t(5356).ReadableStream}let s=null;if(A instanceof p){s=A}else if(i(A)){s=A.stream()}else{s=new p({async pull(A){A.enqueue(typeof E==="string"?(new TextEncoder).encode(E):E);queueMicrotask((()=>g(A)))},start(){},type:undefined})}d(n(s));let C=null;let E=null;let Q=null;let I=null;if(typeof A==="string"){E=A;I="text/plain;charset=UTF-8"}else if(A instanceof URLSearchParams){E=A.toString();I="application/x-www-form-urlencoded;charset=UTF-8"}else if(D(A)){E=new Uint8Array(A.slice())}else if(ArrayBuffer.isView(A)){E=new Uint8Array(A.buffer.slice(A.byteOffset,A.byteOffset+A.byteLength))}else if(o.isFormDataLike(A)){const e=----formdata-undici-${Math.random()}.replace(".","").slice(0,32);const t=--${e}\r\nContent-Disposition: form-data`

SyntaxError: Unexpected token '??=' at wrapSafe (internal/modules/cjs/loader.js:988:16) at Module._compile (internal/modules/cjs/loader.js:1036:27) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32) at Function.Module._load (internal/modules/cjs/loader.js:778:12) at Module.require (internal/modules/cjs/loader.js:961:19) at require (internal/modules/cjs/helpers.js:92:18) at Object. (/Users/macbook/Desktop/microphone_nextjs/node_modules/next/dist/telemetry/post-payload.js:17:20) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! speechmatics-mic-demo@0.1.0 dev: next dev --port 80 npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the speechmatics-mic-demo@0.1.0 dev script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:`

yuriigeivakh commented 8 months ago

Also, I tried to rewrite demo to pure react here https://codesandbox.io/s/speechmatics-demo-react-pwsmcc?file=/src/App.tsx

But there is still some errors, can you help?

nickgerig commented 8 months ago

Hi @yuriigeivakh

You need to use a more recent version of Node.

https://nextjs.org/docs/pages/building-your-application/upgrading/version-13#v13-summary

Let us know if you still can't get it working after that.

yuriigeivakh commented 8 months ago

I tried with 18 node, I have {message: 'Error', type: 'not_authorised', reason: 'Not Authorized'} Even though I passed my API key here is my sandbox which I shared earlier https://codesandbox.io/s/speechmatics-demo-react-pwsmcc?file=/src/App.tsx

nickgerig commented 8 months ago

In your codesandbox you'll need to use a JWT as detailed here https://github.com/speechmatics/speechmatics-js-sdk#jwt-authentication

That's probably the issue.

In the microphone example, where we use NextJS, you add your API key as an environment variable and there is a util that gets the JWT for you https://github.com/speechmatics/speechmatics-js-sdk/blob/main/examples/microphone_nextjs/utils/auth.ts

yuriigeivakh commented 8 months ago

Sure, I pasted my JWT, I just don't want to share it with everyone in the world) So I deleted my API key from sandbox to be able to share with you

Just try with your JWT token in my sandbox, and you'll see that it’s not working even with API key

nickgerig commented 8 months ago

I had already tried with a JWT and seen it working. Sounds like you have it resolved now so I'll close this issue.

yuriigeivakh commented 8 months ago

No, It still doesn’t work for me with the correct API key, the issue is relevant. Maybe you didn't understand me correctly. I don't want to share my API key, it's a bad practice, so I suggest you try with your API key and make sure it's not working

nickgerig commented 8 months ago

@yuriigeivakh using an API key in the browser is not supported for realtime. You need to create a JWT short-lived token and use that.

Please see the docs here: https://github.com/speechmatics/speechmatics-js-sdk#jwt-authentication

curl -L -X POST "https://mp.speechmatics.com/v1/api_keys?type=rt" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $YOUR_API_KEY" \ -d '{"ttl": 3600}'