@corti/dictation-web 0.1.21-rc.2 → 0.1.21-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { Corti } from '@corti/sdk';
1
+ import { type Corti } from '@corti/sdk';
2
2
  import { LitElement } from 'lit';
3
3
  import './components/settings-menu.js';
4
4
  import './components/audio-visualiser.js';
@@ -21,21 +21,9 @@ export declare class CortiDictation extends LitElement {
21
21
  environment: string;
22
22
  tenant: string;
23
23
  accessToken: string;
24
- expiresIn: number | undefined;
24
+ expiresAt: number | undefined;
25
25
  } | undefined;
26
- setAuthConfig(config: {
27
- accessToken: string;
28
- refreshToken?: string;
29
- expiresIn?: number;
30
- refreshExpiresIn?: number;
31
- refreshAccessToken?: (refreshToken?: string) => Promise<{
32
- accessToken: string;
33
- tokenType: string;
34
- expiresIn: number;
35
- refreshToken?: string;
36
- refreshExpiresIn?: number;
37
- }>;
38
- }): ServerConfig;
26
+ setAuthConfig(config: Corti.BearerOptions): Promise<ServerConfig>;
39
27
  get selectedDevice(): MediaDeviceInfo | null;
40
28
  get recordingState(): RecordingState;
41
29
  get devices(): MediaDeviceInfo[];
@@ -88,17 +88,23 @@ export class CortiDictation extends LitElement {
88
88
  throw new Error('Invalid token');
89
89
  }
90
90
  }
91
- setAuthConfig(config) {
91
+ async setAuthConfig(config) {
92
92
  try {
93
- const decoded = decodeToken(config.accessToken);
93
+ const initialToken = 'accessToken' in config
94
+ ? { accessToken: config.accessToken }
95
+ : await config.refreshAccessToken();
96
+ if (!initialToken?.accessToken || typeof initialToken.accessToken !== 'string') {
97
+ throw new Error('Access token is required and must be a string');
98
+ }
99
+ const decoded = decodeToken(initialToken.accessToken);
94
100
  if (!decoded) {
95
101
  throw new Error('Invalid token format');
96
102
  }
97
103
  this._serverConfig = {
98
104
  environment: decoded.environment,
99
105
  tenant: decoded.tenant,
100
- accessToken: config.accessToken,
101
- expiresIn: config.expiresIn ?? decoded.expiresIn,
106
+ accessToken: initialToken.accessToken,
107
+ expiresAt: decoded.expiresAt,
102
108
  refreshToken: config.refreshToken,
103
109
  refreshExpiresIn: config.refreshExpiresIn,
104
110
  refreshAccessToken: config.refreshAccessToken,
@@ -1 +1 @@
1
- {"version":3,"file":"CortiDictation.js","sourceRoot":"","sources":["../src/CortiDictation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Corti } from '@corti/sdk';\n\n// corti-dictation.ts\nimport { html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { RecorderManager } from './RecorderManager.js';\nimport './components/settings-menu.js';\nimport './components/audio-visualiser.js';\nimport './icons/icons.js';\nimport ThemeStyles from './styles/theme.js';\nimport ButtonStyles from './styles/buttons.js';\nimport ComponentStyles from './styles/ComponentStyles.js';\n\nimport type { RecordingState, ServerConfig } from './types.js';\nimport { DEFAULT_DICTATION_CONFIG, LANGUAGES_SUPPORTED } from './constants.js';\nimport CalloutStyles from './styles/callout.js';\nimport { decodeToken } from './utils.js';\n\nexport class CortiDictation extends LitElement {\n static styles = [ButtonStyles, ThemeStyles, ComponentStyles, CalloutStyles];\n\n @property({ type: Object })\n dictationConfig: Corti.TranscribeConfig = DEFAULT_DICTATION_CONFIG;\n\n @property({ type: Array })\n languagesSupported: Corti.TranscribeSupportedLanguage[] = LANGUAGES_SUPPORTED;\n\n @property({ type: Boolean })\n debug_displayAudio: boolean = false;\n\n @state()\n private _serverConfig: ServerConfig | undefined;\n\n @state()\n private _audioLevel: number = 0;\n\n @state()\n private _recordingState: RecordingState = 'stopped';\n\n @state()\n private _selectedDevice: MediaDeviceInfo | undefined;\n\n @state()\n private _devices: MediaDeviceInfo[] = [];\n\n private recorderManager = new RecorderManager();\n\n async connectedCallback() {\n super.connectedCallback();\n const devices = await this.recorderManager.initialize();\n if (devices.selectedDevice) {\n this._selectedDevice = this.recorderManager.selectedDevice;\n this._devices = this.recorderManager.devices;\n this.dispatchEvent(new CustomEvent('ready'));\n }\n\n // Map event names to any extra handling logic\n const eventHandlers: Record<string, (e: CustomEvent) => void> = {\n 'recording-state-changed': e => {\n this._recordingState = e.detail.state;\n },\n 'devices-changed': () => {\n this._devices = [...this.recorderManager.devices];\n this.requestUpdate();\n },\n 'audio-level-changed': e => {\n this._audioLevel = e.detail.audioLevel;\n this.requestUpdate();\n },\n };\n\n const eventsToRelay = [\n 'recording-state-changed',\n 'recording-devices-changed',\n 'audio-level-changed',\n 'error',\n 'transcript',\n 'command',\n 'ready',\n ];\n\n eventsToRelay.forEach(eventName => {\n this.recorderManager.addEventListener(eventName, (e: Event) => {\n const customEvent = e as CustomEvent;\n // Perform any additional handling if defined\n if (eventHandlers[eventName]) {\n eventHandlers[eventName](customEvent);\n }\n // Re-dispatch the event from the component\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: customEvent.detail,\n bubbles: true,\n composed: true,\n }),\n );\n });\n });\n }\n\n public toggleRecording() {\n this._toggleRecording();\n }\n\n public setAccessToken(token: string) {\n try {\n const decoded = decodeToken(token);\n this._serverConfig = decoded;\n return decoded;\n } catch (e) {\n throw new Error('Invalid token');\n }\n }\n\n public setAuthConfig(config: {\n accessToken: string;\n refreshToken?: string;\n expiresIn?: number;\n refreshExpiresIn?: number;\n refreshAccessToken?: (refreshToken?: string) => Promise<{\n accessToken: string;\n tokenType: string;\n expiresIn: number;\n refreshToken?: string;\n refreshExpiresIn?: number;\n }>;\n }) {\n try {\n const decoded = decodeToken(config.accessToken);\n if (!decoded) {\n throw new Error('Invalid token format');\n }\n \n this._serverConfig = {\n environment: decoded.environment,\n tenant: decoded.tenant,\n accessToken: config.accessToken,\n expiresIn: config.expiresIn ?? decoded.expiresIn,\n refreshToken: config.refreshToken,\n refreshExpiresIn: config.refreshExpiresIn,\n refreshAccessToken: config.refreshAccessToken,\n };\n return this._serverConfig;\n } catch (e) {\n throw new Error('Invalid token');\n }\n }\n\n public get selectedDevice(): MediaDeviceInfo | null {\n return this.recorderManager.selectedDevice || null;\n }\n\n public get recordingState(): RecordingState {\n return this._recordingState;\n }\n\n public get devices(): MediaDeviceInfo[] {\n return this._devices;\n }\n\n public async setRecordingDevice(device: MediaDeviceInfo) {\n this.recorderManager.selectedDevice = device;\n this._selectedDevice = device;\n if (!this._serverConfig) return;\n if (this._recordingState === 'recording') {\n await this.recorderManager.stopRecording();\n await this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n });\n }\n }\n\n public setPrimaryLanguage(language: string) {\n if (LANGUAGES_SUPPORTED.includes(language)) {\n this.dictationConfig = {\n ...this.dictationConfig,\n primaryLanguage: language,\n };\n\n // If recording is in progress, restart to apply the language change\n if (this._serverConfig && this._recordingState === 'recording') {\n this.recorderManager.stopRecording();\n this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n debug_displayAudio: this.debug_displayAudio,\n });\n }\n }\n }\n\n _toggleRecording() {\n if (!this._serverConfig) return;\n if (this._recordingState === 'recording') {\n this.recorderManager.stopRecording();\n } else if (this._recordingState === 'stopped') {\n this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n debug_displayAudio: this.debug_displayAudio,\n });\n }\n }\n\n // Handle device change events if needed\n async _onRecordingDevicesChanged(event: Event) {\n const customEvent = event as CustomEvent;\n this.setRecordingDevice(customEvent.detail.selectedDevice);\n }\n\n // Handle language change events\n _onLanguageChanged(event: Event) {\n const customEvent = event as CustomEvent;\n const language = customEvent.detail.language;\n if (language) {\n this.setPrimaryLanguage(language);\n }\n }\n\n render() {\n if (!this._serverConfig) {\n return html` <div style=\"display: none\"></div> `;\n }\n\n const isLoading =\n this._recordingState === 'initializing' ||\n this._recordingState === 'stopping';\n const isRecording = this._recordingState === 'recording';\n return html`\n <div class=\"wrapper\">\n <button\n @click=${this._toggleRecording}\n class=${isRecording ? 'red' : 'accent'}\n >\n ${isLoading\n ? html`<icon-loading-spinner></icon-loading-spinner>`\n : isRecording\n ? html`<icon-recording></icon-recording>`\n : html`<icon-mic-on></icon-mic-on>`}\n <audio-visualiser\n .level=${this._audioLevel}\n .active=${isRecording}\n ></audio-visualiser>\n </button>\n\n <settings-menu\n .selectedDevice=${this._selectedDevice}\n .selectedLanguage=${this.dictationConfig.primaryLanguage}\n ?settingsDisabled=${this._recordingState !== 'stopped'}\n @recording-devices-changed=${this._onRecordingDevicesChanged}\n @language-changed=${this._onLanguageChanged}\n ></settings-menu>\n </div>\n `;\n }\n}\n\nexport default CortiDictation;\n"]}
1
+ {"version":3,"file":"CortiDictation.js","sourceRoot":"","sources":["../src/CortiDictation.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Corti } from '@corti/sdk';\n\n// corti-dictation.ts\nimport { html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { RecorderManager } from './RecorderManager.js';\nimport './components/settings-menu.js';\nimport './components/audio-visualiser.js';\nimport './icons/icons.js';\nimport ThemeStyles from './styles/theme.js';\nimport ButtonStyles from './styles/buttons.js';\nimport ComponentStyles from './styles/ComponentStyles.js';\n\nimport type { RecordingState, ServerConfig } from './types.js';\nimport { DEFAULT_DICTATION_CONFIG, LANGUAGES_SUPPORTED } from './constants.js';\nimport CalloutStyles from './styles/callout.js';\nimport { decodeToken } from './utils.js';\n\nexport class CortiDictation extends LitElement {\n static styles = [ButtonStyles, ThemeStyles, ComponentStyles, CalloutStyles];\n\n @property({ type: Object })\n dictationConfig: Corti.TranscribeConfig = DEFAULT_DICTATION_CONFIG;\n\n @property({ type: Array })\n languagesSupported: Corti.TranscribeSupportedLanguage[] = LANGUAGES_SUPPORTED;\n\n @property({ type: Boolean })\n debug_displayAudio: boolean = false;\n\n @state()\n private _serverConfig: ServerConfig | undefined;\n\n @state()\n private _audioLevel: number = 0;\n\n @state()\n private _recordingState: RecordingState = 'stopped';\n\n @state()\n private _selectedDevice: MediaDeviceInfo | undefined;\n\n @state()\n private _devices: MediaDeviceInfo[] = [];\n\n private recorderManager = new RecorderManager();\n\n async connectedCallback() {\n super.connectedCallback();\n const devices = await this.recorderManager.initialize();\n if (devices.selectedDevice) {\n this._selectedDevice = this.recorderManager.selectedDevice;\n this._devices = this.recorderManager.devices;\n this.dispatchEvent(new CustomEvent('ready'));\n }\n\n // Map event names to any extra handling logic\n const eventHandlers: Record<string, (e: CustomEvent) => void> = {\n 'recording-state-changed': e => {\n this._recordingState = e.detail.state;\n },\n 'devices-changed': () => {\n this._devices = [...this.recorderManager.devices];\n this.requestUpdate();\n },\n 'audio-level-changed': e => {\n this._audioLevel = e.detail.audioLevel;\n this.requestUpdate();\n },\n };\n\n const eventsToRelay = [\n 'recording-state-changed',\n 'recording-devices-changed',\n 'audio-level-changed',\n 'error',\n 'transcript',\n 'command',\n 'ready',\n ];\n\n eventsToRelay.forEach(eventName => {\n this.recorderManager.addEventListener(eventName, (e: Event) => {\n const customEvent = e as CustomEvent;\n // Perform any additional handling if defined\n if (eventHandlers[eventName]) {\n eventHandlers[eventName](customEvent);\n }\n // Re-dispatch the event from the component\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail: customEvent.detail,\n bubbles: true,\n composed: true,\n }),\n );\n });\n });\n }\n\n public toggleRecording() {\n this._toggleRecording();\n }\n\n public setAccessToken(token: string) {\n try {\n const decoded = decodeToken(token);\n this._serverConfig = decoded;\n return decoded;\n } catch (e) {\n throw new Error('Invalid token');\n }\n }\n\n public async setAuthConfig(config: Corti.BearerOptions): Promise<ServerConfig> {\n try {\n const initialToken = 'accessToken' in config\n ? { accessToken: config.accessToken }\n : await config.refreshAccessToken();\n\n if (!initialToken?.accessToken || typeof initialToken.accessToken !== 'string') {\n throw new Error('Access token is required and must be a string');\n }\n\n const decoded = decodeToken(initialToken.accessToken);\n\n if (!decoded) {\n throw new Error('Invalid token format');\n }\n\n this._serverConfig = {\n environment: decoded.environment,\n tenant: decoded.tenant,\n accessToken: initialToken.accessToken,\n expiresAt: decoded.expiresAt,\n refreshToken: config.refreshToken,\n refreshExpiresIn: config.refreshExpiresIn,\n refreshAccessToken: config.refreshAccessToken,\n };\n\n return this._serverConfig;\n } catch (e) {\n throw new Error('Invalid token');\n }\n }\n\n public get selectedDevice(): MediaDeviceInfo | null {\n return this.recorderManager.selectedDevice || null;\n }\n\n public get recordingState(): RecordingState {\n return this._recordingState;\n }\n\n public get devices(): MediaDeviceInfo[] {\n return this._devices;\n }\n\n public async setRecordingDevice(device: MediaDeviceInfo) {\n this.recorderManager.selectedDevice = device;\n this._selectedDevice = device;\n if (!this._serverConfig) return;\n if (this._recordingState === 'recording') {\n await this.recorderManager.stopRecording();\n await this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n });\n }\n }\n\n public setPrimaryLanguage(language: string) {\n if (LANGUAGES_SUPPORTED.includes(language)) {\n this.dictationConfig = {\n ...this.dictationConfig,\n primaryLanguage: language,\n };\n\n // If recording is in progress, restart to apply the language change\n if (this._serverConfig && this._recordingState === 'recording') {\n this.recorderManager.stopRecording();\n this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n debug_displayAudio: this.debug_displayAudio,\n });\n }\n }\n }\n\n _toggleRecording() {\n if (!this._serverConfig) return;\n if (this._recordingState === 'recording') {\n this.recorderManager.stopRecording();\n } else if (this._recordingState === 'stopped') {\n this.recorderManager.startRecording({\n dictationConfig: this.dictationConfig,\n serverConfig: this._serverConfig,\n debug_displayAudio: this.debug_displayAudio,\n });\n }\n }\n\n // Handle device change events if needed\n async _onRecordingDevicesChanged(event: Event) {\n const customEvent = event as CustomEvent;\n this.setRecordingDevice(customEvent.detail.selectedDevice);\n }\n\n // Handle language change events\n _onLanguageChanged(event: Event) {\n const customEvent = event as CustomEvent;\n const language = customEvent.detail.language;\n if (language) {\n this.setPrimaryLanguage(language);\n }\n }\n\n render() {\n if (!this._serverConfig) {\n return html` <div style=\"display: none\"></div> `;\n }\n\n const isLoading =\n this._recordingState === 'initializing' ||\n this._recordingState === 'stopping';\n const isRecording = this._recordingState === 'recording';\n return html`\n <div class=\"wrapper\">\n <button\n @click=${this._toggleRecording}\n class=${isRecording ? 'red' : 'accent'}\n >\n ${isLoading\n ? html`<icon-loading-spinner></icon-loading-spinner>`\n : isRecording\n ? html`<icon-recording></icon-recording>`\n : html`<icon-mic-on></icon-mic-on>`}\n <audio-visualiser\n .level=${this._audioLevel}\n .active=${isRecording}\n ></audio-visualiser>\n </button>\n\n <settings-menu\n .selectedDevice=${this._selectedDevice}\n .selectedLanguage=${this.dictationConfig.primaryLanguage}\n ?settingsDisabled=${this._recordingState !== 'stopped'}\n @recording-devices-changed=${this._onRecordingDevicesChanged}\n @language-changed=${this._onLanguageChanged}\n ></settings-menu>\n </div>\n `;\n }\n}\n\nexport default CortiDictation;\n"]}
@@ -6,16 +6,16 @@ export class DictationService extends EventTarget {
6
6
  this.mediaRecorder = new MediaRecorder(mediaStream);
7
7
  this.serverConfig = serverConfig;
8
8
  this.dictationConfig = dictationConfig;
9
+ const { environment, tenant: tenantName, expiresAt, ...authConfig } = serverConfig;
10
+ const now = Math.floor(Date.now() / 1000);
11
+ const expiresIn = expiresAt ? expiresAt - now : undefined;
9
12
  this.cortiClient = new CortiClient({
10
- environment: serverConfig.environment,
11
- tenantName: serverConfig.tenant,
13
+ environment,
14
+ tenantName,
12
15
  auth: {
13
- accessToken: serverConfig.accessToken,
14
- refreshToken: serverConfig.refreshToken,
15
- expiresIn: serverConfig.expiresIn,
16
- refreshExpiresIn: serverConfig.refreshExpiresIn,
17
- refreshAccessToken: serverConfig.refreshAccessToken,
18
- },
16
+ expiresIn,
17
+ ...authConfig,
18
+ }
19
19
  });
20
20
  this.mediaRecorder.ondataavailable = event => {
21
21
  if (this.webSocket?.readyState === WebSocket.OPEN) {
@@ -1 +1 @@
1
- {"version":3,"file":"DictationService.js","sourceRoot":"","sources":["../src/DictationService.ts"],"names":[],"mappings":"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","sourcesContent":["import { CortiClient, Corti } from '@corti/sdk';\n\nimport type { ServerConfig } from './types.js';\nimport { getErrorMessage } from './utils.js';\n\ntype TranscribeSocket = Awaited<\n ReturnType<CortiClient['transcribe']['connect']>\n>;\n\nexport class DictationService extends EventTarget {\n private mediaRecorder: MediaRecorder;\n private webSocket!: TranscribeSocket;\n private serverConfig: ServerConfig;\n private dictationConfig: Corti.TranscribeConfig;\n private cortiClient: CortiClient;\n\n constructor(\n mediaStream: MediaStream,\n {\n dictationConfig,\n serverConfig,\n }: { dictationConfig: Corti.TranscribeConfig; serverConfig: ServerConfig },\n ) {\n super();\n this.mediaRecorder = new MediaRecorder(mediaStream);\n this.serverConfig = serverConfig;\n this.dictationConfig = dictationConfig;\n\n this.cortiClient = new CortiClient({\n environment: serverConfig.environment,\n tenantName: serverConfig.tenant,\n auth: {\n accessToken: serverConfig.accessToken,\n refreshToken: serverConfig.refreshToken,\n expiresIn: serverConfig.expiresIn,\n refreshExpiresIn: serverConfig.refreshExpiresIn,\n refreshAccessToken: serverConfig.refreshAccessToken,\n },\n });\n\n this.mediaRecorder.ondataavailable = event => {\n if (this.webSocket?.readyState === WebSocket.OPEN) {\n this.webSocket.sendAudio(event.data);\n }\n };\n }\n\n private dispatchCustomEvent(eventName: string, detail?: unknown): void {\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n public async startRecording() {\n if (!this.serverConfig) {\n this.dispatchEvent(\n new CustomEvent('error', {\n detail: 'Invalid token',\n bubbles: true,\n composed: true,\n }),\n );\n return;\n }\n\n this.webSocket = await this.cortiClient.transcribe.connect({\n configuration: this.dictationConfig,\n });\n\n this.webSocket.on('message', message => {\n switch (message.type) {\n case 'CONFIG_ACCEPTED':\n this.mediaRecorder.start(250);\n break;\n case 'transcript':\n this.dispatchCustomEvent('transcript', message);\n break;\n case 'command':\n this.dispatchCustomEvent('command', message);\n break;\n default:\n console.warn(`Unhandled message type: ${message.type}`);\n break;\n }\n });\n\n this.webSocket.on('error', event => {\n this.stopRecording();\n\n this.dispatchCustomEvent('error', getErrorMessage(event));\n });\n\n this.webSocket.on('close', event => {\n this.dispatchCustomEvent('stream-closed', event);\n });\n }\n\n public async stopRecording(): Promise<void> {\n this.mediaRecorder?.stop();\n\n if (this.webSocket.readyState === WebSocket.OPEN) {\n this.webSocket.sendEnd({\n type: 'end',\n });\n }\n\n const timeout: NodeJS.Timeout = setTimeout(() => {\n if (this.webSocket?.readyState === WebSocket.OPEN) {\n this.webSocket.close();\n }\n }, 10000);\n\n this.webSocket.on('close', () => {\n clearTimeout(timeout);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"DictationService.js","sourceRoot":"","sources":["../src/DictationService.ts"],"names":[],"mappings":"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","sourcesContent":["import { CortiClient, Corti } from '@corti/sdk';\n\nimport type { ServerConfig } from './types.js';\nimport { decodeToken, getErrorMessage } from './utils.js';\n\ntype TranscribeSocket = Awaited<\n ReturnType<CortiClient['transcribe']['connect']>\n>;\n\nexport class DictationService extends EventTarget {\n private mediaRecorder: MediaRecorder;\n private webSocket!: TranscribeSocket;\n private serverConfig: ServerConfig;\n private dictationConfig: Corti.TranscribeConfig;\n private cortiClient: CortiClient;\n\n constructor(\n mediaStream: MediaStream,\n {\n dictationConfig,\n serverConfig,\n }: { dictationConfig: Corti.TranscribeConfig; serverConfig: ServerConfig },\n ) {\n super();\n this.mediaRecorder = new MediaRecorder(mediaStream);\n this.serverConfig = serverConfig;\n this.dictationConfig = dictationConfig;\n\n const {\n environment,\n tenant: tenantName,\n expiresAt,\n ...authConfig\n } = serverConfig;\n\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = expiresAt ? expiresAt - now : undefined;\n\n this.cortiClient = new CortiClient({\n environment,\n tenantName,\n auth: {\n expiresIn,\n ...authConfig,\n }\n });\n\n this.mediaRecorder.ondataavailable = event => {\n if (this.webSocket?.readyState === WebSocket.OPEN) {\n this.webSocket.sendAudio(event.data);\n }\n };\n }\n\n private dispatchCustomEvent(eventName: string, detail?: unknown): void {\n this.dispatchEvent(\n new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n public async startRecording() {\n if (!this.serverConfig) {\n this.dispatchEvent(\n new CustomEvent('error', {\n detail: 'Invalid token',\n bubbles: true,\n composed: true,\n }),\n );\n return;\n }\n\n this.webSocket = await this.cortiClient.transcribe.connect({\n configuration: this.dictationConfig,\n });\n\n this.webSocket.on('message', message => {\n switch (message.type) {\n case 'CONFIG_ACCEPTED':\n this.mediaRecorder.start(250);\n break;\n case 'transcript':\n this.dispatchCustomEvent('transcript', message);\n break;\n case 'command':\n this.dispatchCustomEvent('command', message);\n break;\n default:\n console.warn(`Unhandled message type: ${message.type}`);\n break;\n }\n });\n\n this.webSocket.on('error', event => {\n this.stopRecording();\n\n this.dispatchCustomEvent('error', getErrorMessage(event));\n });\n\n this.webSocket.on('close', event => {\n this.dispatchCustomEvent('stream-closed', event);\n });\n }\n\n public async stopRecording(): Promise<void> {\n this.mediaRecorder?.stop();\n\n if (this.webSocket.readyState === WebSocket.OPEN) {\n this.webSocket.sendEnd({\n type: 'end',\n });\n }\n\n const timeout: NodeJS.Timeout = setTimeout(() => {\n if (this.webSocket?.readyState === WebSocket.OPEN) {\n this.webSocket.close();\n }\n }, 10000);\n\n this.webSocket.on('close', () => {\n clearTimeout(timeout);\n });\n }\n}\n"]}
package/dist/bundle.js CHANGED
@@ -709,13 +709,12 @@ function decodeToken(token) {
709
709
  const regex = /^https:\/\/(keycloak|auth)\.([^.]+)\.corti\.app\/realms\/([^/]+)/;
710
710
  const match = issuerUrl.match(regex);
711
711
  if (match) {
712
- const now = Math.floor(Date.now() / 1e3);
713
- const expiresIn = tokenDetails.exp && typeof tokenDetails.exp === "number" ? tokenDetails.exp - now : void 0;
712
+ const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === "number" ? tokenDetails.exp : void 0;
714
713
  return {
715
714
  environment: match[2],
716
715
  tenant: match[3],
717
716
  accessToken: token,
718
- expiresIn: expiresIn && expiresIn > 0 ? expiresIn : void 0
717
+ expiresAt
719
718
  };
720
719
  }
721
720
  }
@@ -3893,6 +3892,70 @@ function isFile(value) {
3893
3892
  return typeof File !== "undefined" && value instanceof File;
3894
3893
  }
3895
3894
 
3895
+ // node_modules/@corti/sdk/dist/esm/custom/RefreshBearerProvider.mjs
3896
+ var __awaiter13 = function(thisArg, _arguments, P2, generator) {
3897
+ function adopt(value) {
3898
+ return value instanceof P2 ? value : new P2(function(resolve) {
3899
+ resolve(value);
3900
+ });
3901
+ }
3902
+ return new (P2 || (P2 = Promise))(function(resolve, reject) {
3903
+ function fulfilled(value) {
3904
+ try {
3905
+ step(generator.next(value));
3906
+ } catch (e5) {
3907
+ reject(e5);
3908
+ }
3909
+ }
3910
+ function rejected(value) {
3911
+ try {
3912
+ step(generator["throw"](value));
3913
+ } catch (e5) {
3914
+ reject(e5);
3915
+ }
3916
+ }
3917
+ function step(result) {
3918
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
3919
+ }
3920
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
3921
+ });
3922
+ };
3923
+ var RefreshBearerProvider = class {
3924
+ constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn }) {
3925
+ this.BUFFER_IN_MINUTES = 2;
3926
+ this._expiresAt = this.getExpiresAt(expiresIn, this.BUFFER_IN_MINUTES);
3927
+ this._refreshExpiresAt = this.getExpiresAt(refreshExpiresIn, 0);
3928
+ this._accessToken = accessToken || "no_token";
3929
+ this._refreshToken = refreshToken;
3930
+ this._refreshAccessToken = refreshAccessToken;
3931
+ }
3932
+ getToken() {
3933
+ return __awaiter13(this, void 0, void 0, function* () {
3934
+ if (this._accessToken && this._expiresAt > /* @__PURE__ */ new Date()) {
3935
+ return Supplier.get(this._accessToken);
3936
+ }
3937
+ return this.refresh();
3938
+ });
3939
+ }
3940
+ refresh() {
3941
+ return __awaiter13(this, void 0, void 0, function* () {
3942
+ if (!this._refreshAccessToken || this._refreshToken && this._refreshExpiresAt < /* @__PURE__ */ new Date()) {
3943
+ return Supplier.get(this._accessToken);
3944
+ }
3945
+ const tokenResponse = yield this._refreshAccessToken(this._refreshToken);
3946
+ this._accessToken = tokenResponse.accessToken;
3947
+ this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES);
3948
+ this._refreshToken = tokenResponse.refreshToken;
3949
+ this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, 0);
3950
+ return this._accessToken;
3951
+ });
3952
+ }
3953
+ getExpiresAt(expiresInSeconds = 0, bufferInMinutes = this.BUFFER_IN_MINUTES) {
3954
+ const now = /* @__PURE__ */ new Date();
3955
+ return new Date(now.getTime() + expiresInSeconds * 1e3 - bufferInMinutes * 60 * 1e3);
3956
+ }
3957
+ };
3958
+
3896
3959
  // node_modules/@corti/sdk/dist/esm/serialization/types/StreamConfigStatusMessageType.mjs
3897
3960
  var StreamConfigStatusMessageType = schemas_exports.enum_([
3898
3961
  "CONFIG_ACCEPTED",
@@ -4685,7 +4748,7 @@ function mergeOnlyDefinedHeaders(...headersArray) {
4685
4748
  }
4686
4749
 
4687
4750
  // node_modules/@corti/sdk/dist/esm/api/resources/auth/client/Client.mjs
4688
- var __awaiter13 = function(thisArg, _arguments, P2, generator) {
4751
+ var __awaiter14 = function(thisArg, _arguments, P2, generator) {
4689
4752
  function adopt(value) {
4690
4753
  return value instanceof P2 ? value : new P2(function(resolve) {
4691
4754
  resolve(value);
@@ -4732,7 +4795,7 @@ var Auth = class {
4732
4795
  return HttpResponsePromise.fromPromise(this.__getToken(request, requestOptions));
4733
4796
  }
4734
4797
  __getToken(request, requestOptions) {
4735
- return __awaiter13(this, void 0, void 0, function* () {
4798
+ return __awaiter14(this, void 0, void 0, function* () {
4736
4799
  var _a, _b;
4737
4800
  const _response = yield fetcher({
4738
4801
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).login, "protocol/openid-connect/token"),
@@ -4788,7 +4851,7 @@ var Auth = class {
4788
4851
  });
4789
4852
  }
4790
4853
  _getAuthorizationHeader() {
4791
- return __awaiter13(this, void 0, void 0, function* () {
4854
+ return __awaiter14(this, void 0, void 0, function* () {
4792
4855
  const bearer = yield Supplier.get(this._options.token);
4793
4856
  if (bearer != null) {
4794
4857
  return `Bearer ${bearer}`;
@@ -4808,7 +4871,7 @@ function getEnvironment(environment) {
4808
4871
  }
4809
4872
 
4810
4873
  // node_modules/@corti/sdk/dist/esm/custom/CortiAuth.mjs
4811
- var __awaiter14 = function(thisArg, _arguments, P2, generator) {
4874
+ var __awaiter15 = function(thisArg, _arguments, P2, generator) {
4812
4875
  function adopt(value) {
4813
4876
  return value instanceof P2 ? value : new P2(function(resolve) {
4814
4877
  resolve(value);
@@ -4852,7 +4915,7 @@ var Auth2 = class extends Auth {
4852
4915
  * Patch: added method to get Authorization URL for Authorization code flow
4853
4916
  */
4854
4917
  authorizeURL(_a, options_1) {
4855
- return __awaiter14(this, arguments, void 0, function* ({ clientId, redirectUri }, options) {
4918
+ return __awaiter15(this, arguments, void 0, function* ({ clientId, redirectUri }, options) {
4856
4919
  var _b;
4857
4920
  const authUrl = new URL(url_exports.join((_b = yield Supplier.get(this._options.baseUrl)) !== null && _b !== void 0 ? _b : (yield Supplier.get(this._options.environment)).login, yield Supplier.get(this._options.tenantName), "protocol/openid-connect/auth"));
4858
4921
  authUrl.searchParams.set("response_type", "code");
@@ -4881,7 +4944,7 @@ var Auth2 = class extends Auth {
4881
4944
  * Patch: copy of this.__getToken with patches
4882
4945
  */
4883
4946
  __getToken_custom(request, requestOptions) {
4884
- return __awaiter14(this, void 0, void 0, function* () {
4947
+ return __awaiter15(this, void 0, void 0, function* () {
4885
4948
  var _a, _b;
4886
4949
  const _response = yield fetcher({
4887
4950
  url: url_exports.join(
@@ -4968,7 +5031,7 @@ var Auth2 = class extends Auth {
4968
5031
  };
4969
5032
 
4970
5033
  // node_modules/@corti/sdk/dist/esm/api/resources/interactions/client/Client.mjs
4971
- var __awaiter15 = function(thisArg, _arguments, P2, generator) {
5034
+ var __awaiter16 = function(thisArg, _arguments, P2, generator) {
4972
5035
  function adopt(value) {
4973
5036
  return value instanceof P2 ? value : new P2(function(resolve) {
4974
5037
  resolve(value);
@@ -5012,8 +5075,8 @@ var Interactions = class {
5012
5075
  * await client.interactions.list()
5013
5076
  */
5014
5077
  list() {
5015
- return __awaiter15(this, arguments, void 0, function* (request = {}, requestOptions) {
5016
- const list2 = HttpResponsePromise.interceptFunction((request2) => __awaiter15(this, void 0, void 0, function* () {
5078
+ return __awaiter16(this, arguments, void 0, function* (request = {}, requestOptions) {
5079
+ const list2 = HttpResponsePromise.interceptFunction((request2) => __awaiter16(this, void 0, void 0, function* () {
5017
5080
  var _a, _b, _c, _d;
5018
5081
  const { sort, direction, pageSize, index, encounterStatus, patient } = request2;
5019
5082
  const _queryParams = {};
@@ -5158,7 +5221,7 @@ var Interactions = class {
5158
5221
  return HttpResponsePromise.fromPromise(this.__create(request, requestOptions));
5159
5222
  }
5160
5223
  __create(request, requestOptions) {
5161
- return __awaiter15(this, void 0, void 0, function* () {
5224
+ return __awaiter16(this, void 0, void 0, function* () {
5162
5225
  var _a, _b;
5163
5226
  const _response = yield fetcher({
5164
5227
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, "interactions/"),
@@ -5252,7 +5315,7 @@ var Interactions = class {
5252
5315
  return HttpResponsePromise.fromPromise(this.__get(id, requestOptions));
5253
5316
  }
5254
5317
  __get(id, requestOptions) {
5255
- return __awaiter15(this, void 0, void 0, function* () {
5318
+ return __awaiter16(this, void 0, void 0, function* () {
5256
5319
  var _a, _b;
5257
5320
  const _response = yield fetcher({
5258
5321
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}`),
@@ -5336,7 +5399,7 @@ var Interactions = class {
5336
5399
  return HttpResponsePromise.fromPromise(this.__delete(id, requestOptions));
5337
5400
  }
5338
5401
  __delete(id, requestOptions) {
5339
- return __awaiter15(this, void 0, void 0, function* () {
5402
+ return __awaiter16(this, void 0, void 0, function* () {
5340
5403
  var _a, _b;
5341
5404
  const _response = yield fetcher({
5342
5405
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}`),
@@ -5412,7 +5475,7 @@ var Interactions = class {
5412
5475
  return HttpResponsePromise.fromPromise(this.__update(id, request, requestOptions));
5413
5476
  }
5414
5477
  __update(id_1) {
5415
- return __awaiter15(this, arguments, void 0, function* (id, request = {}, requestOptions) {
5478
+ return __awaiter16(this, arguments, void 0, function* (id, request = {}, requestOptions) {
5416
5479
  var _a, _b;
5417
5480
  const _response = yield fetcher({
5418
5481
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}`),
@@ -5487,7 +5550,7 @@ var Interactions = class {
5487
5550
  });
5488
5551
  }
5489
5552
  _getAuthorizationHeader() {
5490
- return __awaiter15(this, void 0, void 0, function* () {
5553
+ return __awaiter16(this, void 0, void 0, function* () {
5491
5554
  const bearer = yield Supplier.get(this._options.token);
5492
5555
  if (bearer != null) {
5493
5556
  return `Bearer ${bearer}`;
@@ -5498,7 +5561,7 @@ var Interactions = class {
5498
5561
  };
5499
5562
 
5500
5563
  // node_modules/@corti/sdk/dist/esm/api/resources/recordings/client/Client.mjs
5501
- var __awaiter16 = function(thisArg, _arguments, P2, generator) {
5564
+ var __awaiter17 = function(thisArg, _arguments, P2, generator) {
5502
5565
  function adopt(value) {
5503
5566
  return value instanceof P2 ? value : new P2(function(resolve) {
5504
5567
  resolve(value);
@@ -5547,7 +5610,7 @@ var Recordings = class {
5547
5610
  return HttpResponsePromise.fromPromise(this.__list(id, requestOptions));
5548
5611
  }
5549
5612
  __list(id, requestOptions) {
5550
- return __awaiter16(this, void 0, void 0, function* () {
5613
+ return __awaiter17(this, void 0, void 0, function* () {
5551
5614
  var _a, _b;
5552
5615
  const _response = yield fetcher({
5553
5616
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/`),
@@ -5635,7 +5698,7 @@ var Recordings = class {
5635
5698
  return HttpResponsePromise.fromPromise(this.__upload(uploadable, id, requestOptions));
5636
5699
  }
5637
5700
  __upload(uploadable, id, requestOptions) {
5638
- return __awaiter16(this, void 0, void 0, function* () {
5701
+ return __awaiter17(this, void 0, void 0, function* () {
5639
5702
  var _a, _b;
5640
5703
  const _binaryUploadRequest = yield file_exports.toBinaryUploadRequest(uploadable);
5641
5704
  const _response = yield fetcher({
@@ -5724,7 +5787,7 @@ var Recordings = class {
5724
5787
  return HttpResponsePromise.fromPromise(this.__get(id, recordingId, requestOptions));
5725
5788
  }
5726
5789
  __get(id, recordingId, requestOptions) {
5727
- return __awaiter16(this, void 0, void 0, function* () {
5790
+ return __awaiter17(this, void 0, void 0, function* () {
5728
5791
  var _a, _b;
5729
5792
  const _response = yield fetcher({
5730
5793
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${encodeURIComponent(Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`),
@@ -5815,7 +5878,7 @@ var Recordings = class {
5815
5878
  return HttpResponsePromise.fromPromise(this.__delete(id, recordingId, requestOptions));
5816
5879
  }
5817
5880
  __delete(id, recordingId, requestOptions) {
5818
- return __awaiter16(this, void 0, void 0, function* () {
5881
+ return __awaiter17(this, void 0, void 0, function* () {
5819
5882
  var _a, _b;
5820
5883
  const _response = yield fetcher({
5821
5884
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${encodeURIComponent(Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`),
@@ -5885,7 +5948,7 @@ var Recordings = class {
5885
5948
  });
5886
5949
  }
5887
5950
  _getAuthorizationHeader() {
5888
- return __awaiter16(this, void 0, void 0, function* () {
5951
+ return __awaiter17(this, void 0, void 0, function* () {
5889
5952
  const bearer = yield Supplier.get(this._options.token);
5890
5953
  if (bearer != null) {
5891
5954
  return `Bearer ${bearer}`;
@@ -5896,7 +5959,7 @@ var Recordings = class {
5896
5959
  };
5897
5960
 
5898
5961
  // node_modules/@corti/sdk/dist/esm/api/resources/transcripts/client/Client.mjs
5899
- var __awaiter17 = function(thisArg, _arguments, P2, generator) {
5962
+ var __awaiter18 = function(thisArg, _arguments, P2, generator) {
5900
5963
  function adopt(value) {
5901
5964
  return value instanceof P2 ? value : new P2(function(resolve) {
5902
5965
  resolve(value);
@@ -5947,7 +6010,7 @@ var Transcripts = class {
5947
6010
  return HttpResponsePromise.fromPromise(this.__list(id, request, requestOptions));
5948
6011
  }
5949
6012
  __list(id_1) {
5950
- return __awaiter17(this, arguments, void 0, function* (id, request = {}, requestOptions) {
6013
+ return __awaiter18(this, arguments, void 0, function* (id, request = {}, requestOptions) {
5951
6014
  var _a, _b, _c;
5952
6015
  const { full } = request;
5953
6016
  const _queryParams = {};
@@ -6051,7 +6114,7 @@ var Transcripts = class {
6051
6114
  return HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions));
6052
6115
  }
6053
6116
  __create(id, request, requestOptions) {
6054
- return __awaiter17(this, void 0, void 0, function* () {
6117
+ return __awaiter18(this, void 0, void 0, function* () {
6055
6118
  var _a, _b;
6056
6119
  const _response = yield fetcher({
6057
6120
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/`),
@@ -6151,7 +6214,7 @@ var Transcripts = class {
6151
6214
  return HttpResponsePromise.fromPromise(this.__get(id, transcriptId, requestOptions));
6152
6215
  }
6153
6216
  __get(id, transcriptId, requestOptions) {
6154
- return __awaiter17(this, void 0, void 0, function* () {
6217
+ return __awaiter18(this, void 0, void 0, function* () {
6155
6218
  var _a, _b;
6156
6219
  const _response = yield fetcher({
6157
6220
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${encodeURIComponent(Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`),
@@ -6245,7 +6308,7 @@ var Transcripts = class {
6245
6308
  return HttpResponsePromise.fromPromise(this.__delete(id, transcriptId, requestOptions));
6246
6309
  }
6247
6310
  __delete(id, transcriptId, requestOptions) {
6248
- return __awaiter17(this, void 0, void 0, function* () {
6311
+ return __awaiter18(this, void 0, void 0, function* () {
6249
6312
  var _a, _b;
6250
6313
  const _response = yield fetcher({
6251
6314
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${encodeURIComponent(Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`),
@@ -6311,7 +6374,7 @@ var Transcripts = class {
6311
6374
  });
6312
6375
  }
6313
6376
  _getAuthorizationHeader() {
6314
- return __awaiter17(this, void 0, void 0, function* () {
6377
+ return __awaiter18(this, void 0, void 0, function* () {
6315
6378
  const bearer = yield Supplier.get(this._options.token);
6316
6379
  if (bearer != null) {
6317
6380
  return `Bearer ${bearer}`;
@@ -6322,7 +6385,7 @@ var Transcripts = class {
6322
6385
  };
6323
6386
 
6324
6387
  // node_modules/@corti/sdk/dist/esm/api/resources/facts/client/Client.mjs
6325
- var __awaiter18 = function(thisArg, _arguments, P2, generator) {
6388
+ var __awaiter19 = function(thisArg, _arguments, P2, generator) {
6326
6389
  function adopt(value) {
6327
6390
  return value instanceof P2 ? value : new P2(function(resolve) {
6328
6391
  resolve(value);
@@ -6365,7 +6428,7 @@ var Facts = class {
6365
6428
  return HttpResponsePromise.fromPromise(this.__factGroupsList(requestOptions));
6366
6429
  }
6367
6430
  __factGroupsList(requestOptions) {
6368
- return __awaiter18(this, void 0, void 0, function* () {
6431
+ return __awaiter19(this, void 0, void 0, function* () {
6369
6432
  var _a, _b;
6370
6433
  const _response = yield fetcher({
6371
6434
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, "factgroups/"),
@@ -6434,7 +6497,7 @@ var Facts = class {
6434
6497
  return HttpResponsePromise.fromPromise(this.__list(id, requestOptions));
6435
6498
  }
6436
6499
  __list(id, requestOptions) {
6437
- return __awaiter18(this, void 0, void 0, function* () {
6500
+ return __awaiter19(this, void 0, void 0, function* () {
6438
6501
  var _a, _b;
6439
6502
  const _response = yield fetcher({
6440
6503
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`),
@@ -6515,7 +6578,7 @@ var Facts = class {
6515
6578
  return HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions));
6516
6579
  }
6517
6580
  __create(id, request, requestOptions) {
6518
- return __awaiter18(this, void 0, void 0, function* () {
6581
+ return __awaiter19(this, void 0, void 0, function* () {
6519
6582
  var _a, _b;
6520
6583
  const _response = yield fetcher({
6521
6584
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`),
@@ -6601,7 +6664,7 @@ var Facts = class {
6601
6664
  return HttpResponsePromise.fromPromise(this.__batchUpdate(id, request, requestOptions));
6602
6665
  }
6603
6666
  __batchUpdate(id, request, requestOptions) {
6604
- return __awaiter18(this, void 0, void 0, function* () {
6667
+ return __awaiter19(this, void 0, void 0, function* () {
6605
6668
  var _a, _b;
6606
6669
  const _response = yield fetcher({
6607
6670
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`),
@@ -6684,7 +6747,7 @@ var Facts = class {
6684
6747
  return HttpResponsePromise.fromPromise(this.__update(id, factId, request, requestOptions));
6685
6748
  }
6686
6749
  __update(id_1, factId_1) {
6687
- return __awaiter18(this, arguments, void 0, function* (id, factId, request = {}, requestOptions) {
6750
+ return __awaiter19(this, arguments, void 0, function* (id, factId, request = {}, requestOptions) {
6688
6751
  var _a, _b;
6689
6752
  const _response = yield fetcher({
6690
6753
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/${encodeURIComponent(Uuid.jsonOrThrow(factId, { omitUndefined: true }))}`),
@@ -6751,7 +6814,7 @@ var Facts = class {
6751
6814
  });
6752
6815
  }
6753
6816
  _getAuthorizationHeader() {
6754
- return __awaiter18(this, void 0, void 0, function* () {
6817
+ return __awaiter19(this, void 0, void 0, function* () {
6755
6818
  const bearer = yield Supplier.get(this._options.token);
6756
6819
  if (bearer != null) {
6757
6820
  return `Bearer ${bearer}`;
@@ -6762,7 +6825,7 @@ var Facts = class {
6762
6825
  };
6763
6826
 
6764
6827
  // node_modules/@corti/sdk/dist/esm/api/resources/documents/client/Client.mjs
6765
- var __awaiter19 = function(thisArg, _arguments, P2, generator) {
6828
+ var __awaiter20 = function(thisArg, _arguments, P2, generator) {
6766
6829
  function adopt(value) {
6767
6830
  return value instanceof P2 ? value : new P2(function(resolve) {
6768
6831
  resolve(value);
@@ -6811,7 +6874,7 @@ var Documents = class {
6811
6874
  return HttpResponsePromise.fromPromise(this.__list(id, requestOptions));
6812
6875
  }
6813
6876
  __list(id, requestOptions) {
6814
- return __awaiter19(this, void 0, void 0, function* () {
6877
+ return __awaiter20(this, void 0, void 0, function* () {
6815
6878
  var _a, _b;
6816
6879
  const _response = yield fetcher({
6817
6880
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`),
@@ -6912,7 +6975,7 @@ var Documents = class {
6912
6975
  return HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions));
6913
6976
  }
6914
6977
  __create(id, request, requestOptions) {
6915
- return __awaiter19(this, void 0, void 0, function* () {
6978
+ return __awaiter20(this, void 0, void 0, function* () {
6916
6979
  var _a, _b;
6917
6980
  const _response = yield fetcher({
6918
6981
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`),
@@ -7009,7 +7072,7 @@ var Documents = class {
7009
7072
  return HttpResponsePromise.fromPromise(this.__get(id, documentId, requestOptions));
7010
7073
  }
7011
7074
  __get(id, documentId, requestOptions) {
7012
- return __awaiter19(this, void 0, void 0, function* () {
7075
+ return __awaiter20(this, void 0, void 0, function* () {
7013
7076
  var _a, _b;
7014
7077
  const _response = yield fetcher({
7015
7078
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`),
@@ -7098,7 +7161,7 @@ var Documents = class {
7098
7161
  return HttpResponsePromise.fromPromise(this.__delete(id, documentId, requestOptions));
7099
7162
  }
7100
7163
  __delete(id, documentId, requestOptions) {
7101
- return __awaiter19(this, void 0, void 0, function* () {
7164
+ return __awaiter20(this, void 0, void 0, function* () {
7102
7165
  var _a, _b;
7103
7166
  const _response = yield fetcher({
7104
7167
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`),
@@ -7185,7 +7248,7 @@ var Documents = class {
7185
7248
  return HttpResponsePromise.fromPromise(this.__update(id, documentId, request, requestOptions));
7186
7249
  }
7187
7250
  __update(id_1, documentId_1) {
7188
- return __awaiter19(this, arguments, void 0, function* (id, documentId, request = {}, requestOptions) {
7251
+ return __awaiter20(this, arguments, void 0, function* (id, documentId, request = {}, requestOptions) {
7189
7252
  var _a, _b;
7190
7253
  const _response = yield fetcher({
7191
7254
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `interactions/${encodeURIComponent(Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`),
@@ -7264,7 +7327,7 @@ var Documents = class {
7264
7327
  });
7265
7328
  }
7266
7329
  _getAuthorizationHeader() {
7267
- return __awaiter19(this, void 0, void 0, function* () {
7330
+ return __awaiter20(this, void 0, void 0, function* () {
7268
7331
  const bearer = yield Supplier.get(this._options.token);
7269
7332
  if (bearer != null) {
7270
7333
  return `Bearer ${bearer}`;
@@ -7275,7 +7338,7 @@ var Documents = class {
7275
7338
  };
7276
7339
 
7277
7340
  // node_modules/@corti/sdk/dist/esm/api/resources/templates/client/Client.mjs
7278
- var __awaiter20 = function(thisArg, _arguments, P2, generator) {
7341
+ var __awaiter21 = function(thisArg, _arguments, P2, generator) {
7279
7342
  function adopt(value) {
7280
7343
  return value instanceof P2 ? value : new P2(function(resolve) {
7281
7344
  resolve(value);
@@ -7322,7 +7385,7 @@ var Templates = class {
7322
7385
  return HttpResponsePromise.fromPromise(this.__sectionList(request, requestOptions));
7323
7386
  }
7324
7387
  __sectionList() {
7325
- return __awaiter20(this, arguments, void 0, function* (request = {}, requestOptions) {
7388
+ return __awaiter21(this, arguments, void 0, function* (request = {}, requestOptions) {
7326
7389
  var _a, _b;
7327
7390
  const { org, lang } = request;
7328
7391
  const _queryParams = {};
@@ -7411,7 +7474,7 @@ var Templates = class {
7411
7474
  return HttpResponsePromise.fromPromise(this.__list(request, requestOptions));
7412
7475
  }
7413
7476
  __list() {
7414
- return __awaiter20(this, arguments, void 0, function* (request = {}, requestOptions) {
7477
+ return __awaiter21(this, arguments, void 0, function* (request = {}, requestOptions) {
7415
7478
  var _a, _b;
7416
7479
  const { org, lang, status } = request;
7417
7480
  const _queryParams = {};
@@ -7507,7 +7570,7 @@ var Templates = class {
7507
7570
  return HttpResponsePromise.fromPromise(this.__get(key, requestOptions));
7508
7571
  }
7509
7572
  __get(key, requestOptions) {
7510
- return __awaiter20(this, void 0, void 0, function* () {
7573
+ return __awaiter21(this, void 0, void 0, function* () {
7511
7574
  var _a, _b;
7512
7575
  const _response = yield fetcher({
7513
7576
  url: url_exports.join((_a = yield Supplier.get(this._options.baseUrl)) !== null && _a !== void 0 ? _a : (yield Supplier.get(this._options.environment)).base, `templates/${encodeURIComponent(key)}`),
@@ -7564,7 +7627,7 @@ var Templates = class {
7564
7627
  });
7565
7628
  }
7566
7629
  _getAuthorizationHeader() {
7567
- return __awaiter20(this, void 0, void 0, function* () {
7630
+ return __awaiter21(this, void 0, void 0, function* () {
7568
7631
  const bearer = yield Supplier.get(this._options.token);
7569
7632
  if (bearer != null) {
7570
7633
  return `Bearer ${bearer}`;
@@ -7575,7 +7638,7 @@ var Templates = class {
7575
7638
  };
7576
7639
 
7577
7640
  // node_modules/@corti/sdk/dist/esm/api/resources/stream/client/Socket.mjs
7578
- var __awaiter21 = function(thisArg, _arguments, P2, generator) {
7641
+ var __awaiter22 = function(thisArg, _arguments, P2, generator) {
7579
7642
  function adopt(value) {
7580
7643
  return value instanceof P2 ? value : new P2(function(resolve) {
7581
7644
  resolve(value);
@@ -7710,7 +7773,7 @@ var StreamSocket = class {
7710
7773
  }
7711
7774
  /** Returns a promise that resolves when the websocket is open. */
7712
7775
  waitForOpen() {
7713
- return __awaiter21(this, void 0, void 0, function* () {
7776
+ return __awaiter22(this, void 0, void 0, function* () {
7714
7777
  if (this.socket.readyState === ReconnectingWebSocket.OPEN) {
7715
7778
  return this.socket;
7716
7779
  }
@@ -7740,7 +7803,7 @@ var StreamSocket = class {
7740
7803
  };
7741
7804
 
7742
7805
  // node_modules/@corti/sdk/dist/esm/api/resources/stream/client/Client.mjs
7743
- var __awaiter22 = function(thisArg, _arguments, P2, generator) {
7806
+ var __awaiter23 = function(thisArg, _arguments, P2, generator) {
7744
7807
  function adopt(value) {
7745
7808
  return value instanceof P2 ? value : new P2(function(resolve) {
7746
7809
  resolve(value);
@@ -7772,7 +7835,7 @@ var Stream = class {
7772
7835
  this._options = _options;
7773
7836
  }
7774
7837
  connect(args) {
7775
- return __awaiter22(this, void 0, void 0, function* () {
7838
+ return __awaiter23(this, void 0, void 0, function* () {
7776
7839
  var _a;
7777
7840
  const { id, tenantName, token, headers, debug, reconnectAttempts } = args;
7778
7841
  const _queryParams = {};
@@ -7790,7 +7853,7 @@ var Stream = class {
7790
7853
  });
7791
7854
  }
7792
7855
  _getAuthorizationHeader() {
7793
- return __awaiter22(this, void 0, void 0, function* () {
7856
+ return __awaiter23(this, void 0, void 0, function* () {
7794
7857
  const bearer = yield Supplier.get(this._options.token);
7795
7858
  if (bearer != null) {
7796
7859
  return `Bearer ${bearer}`;
@@ -7831,7 +7894,7 @@ var StreamSocket2 = class extends StreamSocket {
7831
7894
  };
7832
7895
 
7833
7896
  // node_modules/@corti/sdk/dist/esm/custom/CustomStream.mjs
7834
- var __awaiter23 = function(thisArg, _arguments, P2, generator) {
7897
+ var __awaiter24 = function(thisArg, _arguments, P2, generator) {
7835
7898
  function adopt(value) {
7836
7899
  return value instanceof P2 ? value : new P2(function(resolve) {
7837
7900
  resolve(value);
@@ -7877,7 +7940,7 @@ var Stream2 = class extends Stream {
7877
7940
  const _super = Object.create(null, {
7878
7941
  connect: { get: () => super.connect }
7879
7942
  });
7880
- return __awaiter23(this, void 0, void 0, function* () {
7943
+ return __awaiter24(this, void 0, void 0, function* () {
7881
7944
  var { configuration } = _a, args = __rest2(_a, ["configuration"]);
7882
7945
  const fernWs = yield _super.connect.call(this, Object.assign(Object.assign({}, args), { token: (yield this._getAuthorizationHeader()) || "", tenantName: yield Supplier.get(this._options.tenantName) }));
7883
7946
  const ws = new StreamSocket2({ socket: fernWs.socket });
@@ -7929,7 +7992,7 @@ var Stream2 = class extends Stream {
7929
7992
  };
7930
7993
 
7931
7994
  // node_modules/@corti/sdk/dist/esm/api/resources/transcribe/client/Socket.mjs
7932
- var __awaiter24 = function(thisArg, _arguments, P2, generator) {
7995
+ var __awaiter25 = function(thisArg, _arguments, P2, generator) {
7933
7996
  function adopt(value) {
7934
7997
  return value instanceof P2 ? value : new P2(function(resolve) {
7935
7998
  resolve(value);
@@ -8064,7 +8127,7 @@ var TranscribeSocket = class {
8064
8127
  }
8065
8128
  /** Returns a promise that resolves when the websocket is open. */
8066
8129
  waitForOpen() {
8067
- return __awaiter24(this, void 0, void 0, function* () {
8130
+ return __awaiter25(this, void 0, void 0, function* () {
8068
8131
  if (this.socket.readyState === ReconnectingWebSocket.OPEN) {
8069
8132
  return this.socket;
8070
8133
  }
@@ -8094,7 +8157,7 @@ var TranscribeSocket = class {
8094
8157
  };
8095
8158
 
8096
8159
  // node_modules/@corti/sdk/dist/esm/api/resources/transcribe/client/Client.mjs
8097
- var __awaiter25 = function(thisArg, _arguments, P2, generator) {
8160
+ var __awaiter26 = function(thisArg, _arguments, P2, generator) {
8098
8161
  function adopt(value) {
8099
8162
  return value instanceof P2 ? value : new P2(function(resolve) {
8100
8163
  resolve(value);
@@ -8126,7 +8189,7 @@ var Transcribe = class {
8126
8189
  this._options = _options;
8127
8190
  }
8128
8191
  connect(args) {
8129
- return __awaiter25(this, void 0, void 0, function* () {
8192
+ return __awaiter26(this, void 0, void 0, function* () {
8130
8193
  var _a;
8131
8194
  const { tenantName, token, headers, debug, reconnectAttempts } = args;
8132
8195
  const _queryParams = {};
@@ -8144,7 +8207,7 @@ var Transcribe = class {
8144
8207
  });
8145
8208
  }
8146
8209
  _getAuthorizationHeader() {
8147
- return __awaiter25(this, void 0, void 0, function* () {
8210
+ return __awaiter26(this, void 0, void 0, function* () {
8148
8211
  const bearer = yield Supplier.get(this._options.token);
8149
8212
  if (bearer != null) {
8150
8213
  return `Bearer ${bearer}`;
@@ -8185,7 +8248,7 @@ var TranscribeSocket2 = class extends TranscribeSocket {
8185
8248
  };
8186
8249
 
8187
8250
  // node_modules/@corti/sdk/dist/esm/custom/CustomTranscribe.mjs
8188
- var __awaiter26 = function(thisArg, _arguments, P2, generator) {
8251
+ var __awaiter27 = function(thisArg, _arguments, P2, generator) {
8189
8252
  function adopt(value) {
8190
8253
  return value instanceof P2 ? value : new P2(function(resolve) {
8191
8254
  resolve(value);
@@ -8231,7 +8294,7 @@ var Transcribe2 = class extends Transcribe {
8231
8294
  const _super = Object.create(null, {
8232
8295
  connect: { get: () => super.connect }
8233
8296
  });
8234
- return __awaiter26(this, arguments, void 0, function* (_a = {}) {
8297
+ return __awaiter27(this, arguments, void 0, function* (_a = {}) {
8235
8298
  var { configuration } = _a, args = __rest3(_a, ["configuration"]);
8236
8299
  const fernWs = yield _super.connect.call(this, Object.assign(Object.assign({}, args), { token: (yield this._getAuthorizationHeader()) || "", tenantName: yield Supplier.get(this._options.tenantName) }));
8237
8300
  const ws = new TranscribeSocket2({ socket: fernWs.socket });
@@ -8282,70 +8345,6 @@ var Transcribe2 = class extends Transcribe {
8282
8345
  }
8283
8346
  };
8284
8347
 
8285
- // node_modules/@corti/sdk/dist/esm/custom/RefreshBearerProvider.mjs
8286
- var __awaiter27 = function(thisArg, _arguments, P2, generator) {
8287
- function adopt(value) {
8288
- return value instanceof P2 ? value : new P2(function(resolve) {
8289
- resolve(value);
8290
- });
8291
- }
8292
- return new (P2 || (P2 = Promise))(function(resolve, reject) {
8293
- function fulfilled(value) {
8294
- try {
8295
- step(generator.next(value));
8296
- } catch (e5) {
8297
- reject(e5);
8298
- }
8299
- }
8300
- function rejected(value) {
8301
- try {
8302
- step(generator["throw"](value));
8303
- } catch (e5) {
8304
- reject(e5);
8305
- }
8306
- }
8307
- function step(result) {
8308
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
8309
- }
8310
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8311
- });
8312
- };
8313
- var RefreshBearerProvider = class {
8314
- constructor({ accessToken, refreshAccessToken, refreshToken, refreshExpiresIn, expiresIn }) {
8315
- this.BUFFER_IN_MINUTES = 2;
8316
- this._expiresAt = this.getExpiresAt(expiresIn, this.BUFFER_IN_MINUTES);
8317
- this._refreshExpiresAt = this.getExpiresAt(refreshExpiresIn, 0);
8318
- this._accessToken = accessToken || "no_token";
8319
- this._refreshToken = refreshToken;
8320
- this._refreshAccessToken = refreshAccessToken;
8321
- }
8322
- getToken() {
8323
- return __awaiter27(this, void 0, void 0, function* () {
8324
- if (this._accessToken && this._expiresAt > /* @__PURE__ */ new Date()) {
8325
- return Supplier.get(this._accessToken);
8326
- }
8327
- return this.refresh();
8328
- });
8329
- }
8330
- refresh() {
8331
- return __awaiter27(this, void 0, void 0, function* () {
8332
- if (!this._refreshAccessToken || this._refreshToken && this._refreshExpiresAt < /* @__PURE__ */ new Date()) {
8333
- return Supplier.get(this._accessToken);
8334
- }
8335
- const tokenResponse = yield this._refreshAccessToken(this._refreshToken);
8336
- this._accessToken = tokenResponse.accessToken;
8337
- this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES);
8338
- this._refreshToken = tokenResponse.refreshToken;
8339
- this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, 0);
8340
- return this._accessToken;
8341
- });
8342
- }
8343
- getExpiresAt(expiresInSeconds = 0, bufferInMinutes = this.BUFFER_IN_MINUTES) {
8344
- const now = /* @__PURE__ */ new Date();
8345
- return new Date(now.getTime() + expiresInSeconds * 1e3 - bufferInMinutes * 60 * 1e3);
8346
- }
8347
- };
8348
-
8349
8348
  // node_modules/@corti/sdk/dist/esm/version.mjs
8350
8349
  var SDK_VERSION = "0.1.1";
8351
8350
 
@@ -8457,15 +8456,15 @@ var DictationService = class extends EventTarget {
8457
8456
  this.mediaRecorder = new MediaRecorder(mediaStream);
8458
8457
  this.serverConfig = serverConfig;
8459
8458
  this.dictationConfig = dictationConfig;
8459
+ const { environment, tenant: tenantName, expiresAt, ...authConfig } = serverConfig;
8460
+ const now = Math.floor(Date.now() / 1e3);
8461
+ const expiresIn = expiresAt ? expiresAt - now : void 0;
8460
8462
  this.cortiClient = new CortiClient({
8461
- environment: serverConfig.environment,
8462
- tenantName: serverConfig.tenant,
8463
+ environment,
8464
+ tenantName,
8463
8465
  auth: {
8464
- accessToken: serverConfig.accessToken,
8465
- refreshToken: serverConfig.refreshToken,
8466
- expiresIn: serverConfig.expiresIn,
8467
- refreshExpiresIn: serverConfig.refreshExpiresIn,
8468
- refreshAccessToken: serverConfig.refreshAccessToken
8466
+ expiresIn,
8467
+ ...authConfig
8469
8468
  }
8470
8469
  });
8471
8470
  this.mediaRecorder.ondataavailable = (event) => {
@@ -9368,17 +9367,21 @@ var CortiDictation = class extends i4 {
9368
9367
  throw new Error("Invalid token");
9369
9368
  }
9370
9369
  }
9371
- setAuthConfig(config) {
9370
+ async setAuthConfig(config) {
9372
9371
  try {
9373
- const decoded = decodeToken(config.accessToken);
9372
+ const initialToken = "accessToken" in config ? { accessToken: config.accessToken } : await config.refreshAccessToken();
9373
+ if (!initialToken?.accessToken || typeof initialToken.accessToken !== "string") {
9374
+ throw new Error("Access token is required and must be a string");
9375
+ }
9376
+ const decoded = decodeToken(initialToken.accessToken);
9374
9377
  if (!decoded) {
9375
9378
  throw new Error("Invalid token format");
9376
9379
  }
9377
9380
  this._serverConfig = {
9378
9381
  environment: decoded.environment,
9379
9382
  tenant: decoded.tenant,
9380
- accessToken: config.accessToken,
9381
- expiresIn: config.expiresIn ?? decoded.expiresIn,
9383
+ accessToken: initialToken.accessToken,
9384
+ expiresAt: decoded.expiresAt,
9382
9385
  refreshToken: config.refreshToken,
9383
9386
  refreshExpiresIn: config.refreshExpiresIn,
9384
9387
  refreshAccessToken: config.refreshAccessToken
package/dist/types.d.ts CHANGED
@@ -1,16 +1,7 @@
1
+ import { type Corti } from '@corti/sdk';
1
2
  export type RecordingState = 'initializing' | 'recording' | 'stopping' | 'stopped';
2
- export interface ServerConfig {
3
+ export type ServerConfig = {
3
4
  environment: string;
4
5
  tenant: string;
5
- accessToken: string;
6
- refreshToken?: string;
7
- expiresIn?: number;
8
- refreshExpiresIn?: number;
9
- refreshAccessToken?: (refreshToken?: string) => Promise<{
10
- accessToken: string;
11
- tokenType: string;
12
- expiresIn: number;
13
- refreshToken?: string;
14
- refreshExpiresIn?: number;
15
- }>;
16
- }
6
+ expiresAt?: number;
7
+ } & Corti.BearerOptions;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type RecordingState =\n | 'initializing'\n | 'recording'\n | 'stopping'\n | 'stopped';\n\nexport interface ServerConfig {\n environment: string;\n tenant: string;\n accessToken: string;\n refreshToken?: string;\n expiresIn?: number;\n refreshExpiresIn?: number;\n refreshAccessToken?: (refreshToken?: string) => Promise<{\n accessToken: string;\n tokenType: string;\n expiresIn: number;\n refreshToken?: string;\n refreshExpiresIn?: number;\n }>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { type Corti } from '@corti/sdk';\n\nexport type RecordingState =\n | 'initializing'\n | 'recording'\n | 'stopping'\n | 'stopped';\n\nexport type ServerConfig = {\n environment: string;\n tenant: string;\n expiresAt?: number;\n} & Corti.BearerOptions;\n"]}
package/dist/utils.d.ts CHANGED
@@ -54,7 +54,7 @@ export declare function decodeToken(token: string): {
54
54
  environment: string;
55
55
  tenant: string;
56
56
  accessToken: string;
57
- expiresIn: number | undefined;
57
+ expiresAt: number | undefined;
58
58
  } | undefined;
59
59
  export declare function getMediaStream(deviceId?: string): Promise<MediaStream>;
60
60
  export declare function getErrorMessage(event: Error): any;
package/dist/utils.js CHANGED
@@ -136,14 +136,14 @@ export function decodeToken(token) {
136
136
  const match = issuerUrl.match(regex);
137
137
  // If the issuer URL matches the expected pattern, return the extracted values along with the token
138
138
  if (match) {
139
- // Calculate expiration time in seconds from now
140
- const now = Math.floor(Date.now() / 1000);
141
- const expiresIn = tokenDetails.exp && typeof tokenDetails.exp === 'number' ? tokenDetails.exp - now : undefined;
139
+ const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === 'number'
140
+ ? tokenDetails.exp
141
+ : undefined;
142
142
  return {
143
143
  environment: match[2],
144
144
  tenant: match[3],
145
145
  accessToken: token,
146
- expiresIn: expiresIn && expiresIn > 0 ? expiresIn : undefined,
146
+ expiresAt,
147
147
  };
148
148
  }
149
149
  }
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/**\n * Returns the localized name of a language given its BCP-47 code.\n *\n * @param languageCode - The BCP-47 language code (e.g. \"en\")\n * @returns The localized language name (e.g. \"English\") or the original code if unavailable.\n */\nexport function getLanguageName(languageCode: string): string {\n const userLocale = navigator.language || 'en';\n const displayNames = new Intl.DisplayNames([userLocale], {\n type: 'language',\n });\n const languageName = displayNames.of(languageCode);\n return languageName || languageCode;\n}\n\n/**\n * Requests access to the microphone.\n *\n * This function checks if the microphone permission is in \"prompt\" state, then requests\n * access and stops any active tracks immediately. It also logs if permission is already granted.\n *\n * @returns A promise that resolves when the permission request is complete.\n */\nexport async function requestMicAccess(): Promise<void> {\n try {\n // Fallback if Permissions API is not available\n if (!navigator.permissions) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n return;\n }\n\n const permissionStatus = await navigator.permissions.query({\n // eslint-disable-next-line no-undef\n name: 'microphone' as PermissionName,\n });\n\n if (permissionStatus.state === 'prompt') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n } else if (permissionStatus.state === 'denied') {\n console.warn('Microphone permission is denied.');\n }\n } catch (error) {\n console.error('Error checking/requesting microphone permission:', error);\n }\n}\n\n/**\n * Retrieves available audio input devices.\n *\n * This function uses the mediaDevices API to enumerate devices and filters out those\n * which are audio inputs. In some browsers, you may need to request user media before\n * device labels are populated.\n *\n * @returns A promise that resolves with an object containing:\n * - `devices`: an array of MediaDeviceInfo objects for audio inputs.\n * - `defaultDeviceId`: the deviceId of the first audio input, if available.\n */\nexport async function getAudioDevices(): Promise<{\n devices: MediaDeviceInfo[];\n defaultDevice?: MediaDeviceInfo;\n}> {\n if (!navigator.mediaDevices?.enumerateDevices) {\n console.error('Media devices API not supported.');\n return { devices: [] };\n }\n\n await requestMicAccess();\n\n try {\n // Optionally: await navigator.mediaDevices.getUserMedia({ audio: true });\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(device => device.kind === 'audioinput');\n const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;\n return { devices: audioDevices, defaultDevice };\n } catch (error) {\n console.error('Error enumerating devices:', error);\n return { devices: [] };\n }\n}\n\n/**\n * Decodes a JWT token and extracts environment and tenant details from its issuer URL.\n *\n * This function assumes the JWT token follows the standard header.payload.signature format.\n * It decodes the payload from base64 URL format, parses it as JSON, and then uses a regex\n * to extract the `environment` and `tenant` from the issuer URL (iss field) if it matches the pattern:\n * https://keycloak.{environment}.corti.app/realms/{tenant}.\n *\n * @param token - A JSON Web Token (JWT) string.\n * @returns An object containing:\n * - `environment`: The extracted environment from the issuer URL.\n * - `tenant`: The extracted tenant from the issuer URL.\n * - `accessToken`: The original token string.\n * If the issuer URL doesn't match the expected format, the function returns the full decoded token details.\n *\n * @throws Will throw an error if:\n * - The token format is invalid.\n * - The base64 decoding or URI decoding fails.\n * - The JSON payload is invalid.\n * - The token payload does not contain an issuer (iss) field.\n */\nexport function decodeToken(token: string) {\n // Validate the token structure (should contain at least header and payload parts)\n const parts = token.split('.');\n if (parts.length < 2) {\n throw new Error('Invalid token format');\n }\n\n // Retrieve the payload (second part) of the JWT token\n const base64Url = parts[1];\n\n // Replace URL-safe characters to match standard base64 encoding\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n\n // Decode the base64 string into a JSON string\n let jsonPayload: string;\n try {\n jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n );\n } catch (error) {\n throw new Error('Failed to decode token payload');\n }\n\n // Parse the JSON string to obtain token details\n let tokenDetails: { iss: string; [key: string]: unknown };\n try {\n tokenDetails = JSON.parse(jsonPayload);\n } catch (error) {\n throw new Error('Invalid JSON payload in token');\n }\n\n // Extract the issuer URL from the token details\n const issuerUrl: string = tokenDetails.iss;\n if (!issuerUrl) {\n throw new Error('Token payload does not contain an issuer (iss) field');\n }\n\n // Regex to extract environment and tenant from issuer URL:\n // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}\n // Note: Unnecessary escapes in character classes have been removed.\n const regex =\n /^https:\\/\\/(keycloak|auth)\\.([^.]+)\\.corti\\.app\\/realms\\/([^/]+)/;\n const match = issuerUrl.match(regex);\n\n // If the issuer URL matches the expected pattern, return the extracted values along with the token\n if (match) {\n // Calculate expiration time in seconds from now\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = tokenDetails.exp && typeof tokenDetails.exp === 'number' ? tokenDetails.exp - now : undefined;\n \n return {\n environment: match[2],\n tenant: match[3],\n accessToken: token,\n expiresIn: expiresIn && expiresIn > 0 ? expiresIn : undefined,\n };\n }\n}\n\nexport async function getMediaStream(deviceId?: string): Promise<MediaStream> {\n if (!deviceId) {\n throw new Error('No device ID provided');\n }\n\n if (deviceId === 'display_audio') {\n const stream = await navigator.mediaDevices.getDisplayMedia({\n audio: true,\n video: true,\n });\n stream.getTracks().forEach(track => {\n if (track.kind === 'video') {\n stream.removeTrack(track);\n }\n });\n return stream;\n }\n\n // Get media stream and initialize audio service.\n const constraints: MediaStreamConstraints =\n deviceId !== 'default'\n ? { audio: { deviceId: { exact: deviceId } } }\n : { audio: true };\n\n return await navigator.mediaDevices.getUserMedia(constraints);\n}\n\nexport function getErrorMessage(event: Error) {\n try {\n return JSON.parse(event.message);\n } catch {\n return event?.message || event;\n }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/**\n * Returns the localized name of a language given its BCP-47 code.\n *\n * @param languageCode - The BCP-47 language code (e.g. \"en\")\n * @returns The localized language name (e.g. \"English\") or the original code if unavailable.\n */\nexport function getLanguageName(languageCode: string): string {\n const userLocale = navigator.language || 'en';\n const displayNames = new Intl.DisplayNames([userLocale], {\n type: 'language',\n });\n const languageName = displayNames.of(languageCode);\n return languageName || languageCode;\n}\n\n/**\n * Requests access to the microphone.\n *\n * This function checks if the microphone permission is in \"prompt\" state, then requests\n * access and stops any active tracks immediately. It also logs if permission is already granted.\n *\n * @returns A promise that resolves when the permission request is complete.\n */\nexport async function requestMicAccess(): Promise<void> {\n try {\n // Fallback if Permissions API is not available\n if (!navigator.permissions) {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n return;\n }\n\n const permissionStatus = await navigator.permissions.query({\n // eslint-disable-next-line no-undef\n name: 'microphone' as PermissionName,\n });\n\n if (permissionStatus.state === 'prompt') {\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n stream.getTracks().forEach(track => track.stop());\n } else if (permissionStatus.state === 'denied') {\n console.warn('Microphone permission is denied.');\n }\n } catch (error) {\n console.error('Error checking/requesting microphone permission:', error);\n }\n}\n\n/**\n * Retrieves available audio input devices.\n *\n * This function uses the mediaDevices API to enumerate devices and filters out those\n * which are audio inputs. In some browsers, you may need to request user media before\n * device labels are populated.\n *\n * @returns A promise that resolves with an object containing:\n * - `devices`: an array of MediaDeviceInfo objects for audio inputs.\n * - `defaultDeviceId`: the deviceId of the first audio input, if available.\n */\nexport async function getAudioDevices(): Promise<{\n devices: MediaDeviceInfo[];\n defaultDevice?: MediaDeviceInfo;\n}> {\n if (!navigator.mediaDevices?.enumerateDevices) {\n console.error('Media devices API not supported.');\n return { devices: [] };\n }\n\n await requestMicAccess();\n\n try {\n // Optionally: await navigator.mediaDevices.getUserMedia({ audio: true });\n const devices = await navigator.mediaDevices.enumerateDevices();\n const audioDevices = devices.filter(device => device.kind === 'audioinput');\n const defaultDevice = audioDevices.length > 0 ? audioDevices[0] : undefined;\n return { devices: audioDevices, defaultDevice };\n } catch (error) {\n console.error('Error enumerating devices:', error);\n return { devices: [] };\n }\n}\n\n/**\n * Decodes a JWT token and extracts environment and tenant details from its issuer URL.\n *\n * This function assumes the JWT token follows the standard header.payload.signature format.\n * It decodes the payload from base64 URL format, parses it as JSON, and then uses a regex\n * to extract the `environment` and `tenant` from the issuer URL (iss field) if it matches the pattern:\n * https://keycloak.{environment}.corti.app/realms/{tenant}.\n *\n * @param token - A JSON Web Token (JWT) string.\n * @returns An object containing:\n * - `environment`: The extracted environment from the issuer URL.\n * - `tenant`: The extracted tenant from the issuer URL.\n * - `accessToken`: The original token string.\n * If the issuer URL doesn't match the expected format, the function returns the full decoded token details.\n *\n * @throws Will throw an error if:\n * - The token format is invalid.\n * - The base64 decoding or URI decoding fails.\n * - The JSON payload is invalid.\n * - The token payload does not contain an issuer (iss) field.\n */\nexport function decodeToken(token: string) {\n // Validate the token structure (should contain at least header and payload parts)\n const parts = token.split('.');\n if (parts.length < 2) {\n throw new Error('Invalid token format');\n }\n\n // Retrieve the payload (second part) of the JWT token\n const base64Url = parts[1];\n\n // Replace URL-safe characters to match standard base64 encoding\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n\n // Decode the base64 string into a JSON string\n let jsonPayload: string;\n try {\n jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n );\n } catch (error) {\n throw new Error('Failed to decode token payload');\n }\n\n // Parse the JSON string to obtain token details\n let tokenDetails: { iss: string; [key: string]: unknown };\n try {\n tokenDetails = JSON.parse(jsonPayload);\n } catch (error) {\n throw new Error('Invalid JSON payload in token');\n }\n\n // Extract the issuer URL from the token details\n const issuerUrl: string = tokenDetails.iss;\n if (!issuerUrl) {\n throw new Error('Token payload does not contain an issuer (iss) field');\n }\n\n // Regex to extract environment and tenant from issuer URL:\n // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant}\n // Note: Unnecessary escapes in character classes have been removed.\n const regex =\n /^https:\\/\\/(keycloak|auth)\\.([^.]+)\\.corti\\.app\\/realms\\/([^/]+)/;\n const match = issuerUrl.match(regex);\n\n // If the issuer URL matches the expected pattern, return the extracted values along with the token\n if (match) {\n const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === 'number'\n ? tokenDetails.exp\n : undefined;\n\n return {\n environment: match[2],\n tenant: match[3],\n accessToken: token,\n expiresAt,\n };\n }\n}\n\nexport async function getMediaStream(deviceId?: string): Promise<MediaStream> {\n if (!deviceId) {\n throw new Error('No device ID provided');\n }\n\n if (deviceId === 'display_audio') {\n const stream = await navigator.mediaDevices.getDisplayMedia({\n audio: true,\n video: true,\n });\n stream.getTracks().forEach(track => {\n if (track.kind === 'video') {\n stream.removeTrack(track);\n }\n });\n return stream;\n }\n\n // Get media stream and initialize audio service.\n const constraints: MediaStreamConstraints =\n deviceId !== 'default'\n ? { audio: { deviceId: { exact: deviceId } } }\n : { audio: true };\n\n return await navigator.mediaDevices.getUserMedia(constraints);\n}\n\nexport function getErrorMessage(event: Error) {\n try {\n return JSON.parse(event.message);\n } catch {\n return event?.message || event;\n }\n}\n"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@corti/dictation-web",
3
3
  "description": "Web component for Corti Dictation",
4
4
  "author": "Corti ApS",
5
- "version": "0.1.21-rc.2",
5
+ "version": "0.1.21-rc.4",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",