@deepgram/sdk 5.0.0-alpha.1 → 5.0.0-alpha.2
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.
- package/README.md +44 -1
- package/dist/browser/index.global.js +8674 -0
- package/dist/cjs/BaseClient.js +3 -0
- package/dist/cjs/CustomClient.js +113 -12
- package/dist/cjs/core/websocket/ws.d.ts +0 -1
- package/dist/cjs/core/websocket/ws.js +9 -47
- package/dist/cjs/version.d.ts +1 -0
- package/dist/cjs/version.js +4 -0
- package/dist/esm/BaseClient.mjs +3 -0
- package/dist/esm/CustomClient.mjs +113 -12
- package/dist/esm/core/websocket/ws.d.mts +0 -1
- package/dist/esm/core/websocket/ws.mjs +9 -47
- package/dist/esm/version.d.mts +1 -0
- package/dist/esm/version.mjs +1 -0
- package/package.json +4 -29
package/dist/cjs/BaseClient.js
CHANGED
|
@@ -42,6 +42,9 @@ const core = __importStar(require("./core/index.js"));
|
|
|
42
42
|
function normalizeClientOptions(options) {
|
|
43
43
|
const headers = (0, headers_js_1.mergeHeaders)({
|
|
44
44
|
"X-Fern-Language": "JavaScript",
|
|
45
|
+
"X-Fern-SDK-Name": "",
|
|
46
|
+
"X-Fern-SDK-Version": "0.0.219",
|
|
47
|
+
"User-Agent": "/0.0.219",
|
|
45
48
|
"X-Fern-Runtime": core.RUNTIME.type,
|
|
46
49
|
"X-Fern-Runtime-Version": core.RUNTIME.version,
|
|
47
50
|
}, options === null || options === void 0 ? void 0 : options.headers);
|
package/dist/cjs/CustomClient.js
CHANGED
|
@@ -60,6 +60,19 @@ const headers_js_1 = require("./core/headers.js");
|
|
|
60
60
|
const json_js_1 = require("./core/json.js");
|
|
61
61
|
const core = __importStar(require("./core/index.js"));
|
|
62
62
|
const environments = __importStar(require("./environments.js"));
|
|
63
|
+
const index_js_1 = require("./core/runtime/index.js");
|
|
64
|
+
// Import ws library for Node.js (will be undefined in browser)
|
|
65
|
+
let NodeWebSocket;
|
|
66
|
+
try {
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
68
|
+
NodeWebSocket = require("ws");
|
|
69
|
+
// Handle both default export and named export
|
|
70
|
+
NodeWebSocket = NodeWebSocket.WebSocket || NodeWebSocket.default || NodeWebSocket;
|
|
71
|
+
}
|
|
72
|
+
catch (_a) {
|
|
73
|
+
// ws not available (e.g., in browser)
|
|
74
|
+
NodeWebSocket = undefined;
|
|
75
|
+
}
|
|
63
76
|
/**
|
|
64
77
|
* Custom wrapper around DeepgramClient that ensures the custom websocket implementation
|
|
65
78
|
* from ws.ts is always used, even if the auto-generated code changes.
|
|
@@ -130,24 +143,78 @@ class WrappedSpeakClient extends Client_js_3.SpeakClient {
|
|
|
130
143
|
return new WrappedSpeakV1Client(this._options);
|
|
131
144
|
}
|
|
132
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Helper function to get WebSocket class and handle headers/protocols based on runtime.
|
|
148
|
+
* In Node.js, use the 'ws' library which supports headers.
|
|
149
|
+
* In browser, use Sec-WebSocket-Protocol for authentication since headers aren't supported.
|
|
150
|
+
*/
|
|
151
|
+
function getWebSocketOptions(headers) {
|
|
152
|
+
const options = {};
|
|
153
|
+
// Check if we're in a browser environment (browser or web-worker)
|
|
154
|
+
const isBrowser = index_js_1.RUNTIME.type === "browser" || index_js_1.RUNTIME.type === "web-worker";
|
|
155
|
+
// In Node.js, ensure we use the 'ws' library which supports headers
|
|
156
|
+
if (index_js_1.RUNTIME.type === "node" && NodeWebSocket) {
|
|
157
|
+
options.WebSocket = NodeWebSocket;
|
|
158
|
+
options.headers = headers;
|
|
159
|
+
}
|
|
160
|
+
else if (isBrowser) {
|
|
161
|
+
// In browser, native WebSocket doesn't support custom headers
|
|
162
|
+
// Extract Authorization header and use Sec-WebSocket-Protocol instead
|
|
163
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
164
|
+
const browserHeaders = Object.assign({}, headers);
|
|
165
|
+
// Remove Authorization from headers since it won't work in browser
|
|
166
|
+
delete browserHeaders.Authorization;
|
|
167
|
+
delete browserHeaders.authorization;
|
|
168
|
+
options.headers = browserHeaders;
|
|
169
|
+
// If we have an Authorization header, extract the token and format as protocols
|
|
170
|
+
// Deepgram expects:
|
|
171
|
+
// - For API keys: Sec-WebSocket-Protocol: token,API_KEY_GOES_HERE
|
|
172
|
+
// - For Bearer tokens: Sec-WebSocket-Protocol: bearer,TOKEN_GOES_HERE
|
|
173
|
+
// The comma separates multiple protocols, so we pass them as an array
|
|
174
|
+
if (authHeader && typeof authHeader === "string") {
|
|
175
|
+
if (authHeader.startsWith("Token ")) {
|
|
176
|
+
// API key: "Token API_KEY" -> ["token", "API_KEY"]
|
|
177
|
+
const apiKey = authHeader.substring(6); // Remove "Token " prefix
|
|
178
|
+
options.protocols = ["token", apiKey];
|
|
179
|
+
}
|
|
180
|
+
else if (authHeader.startsWith("Bearer ")) {
|
|
181
|
+
// Access token: "Bearer TOKEN" -> ["bearer", "TOKEN"]
|
|
182
|
+
const token = authHeader.substring(7); // Remove "Bearer " prefix
|
|
183
|
+
options.protocols = ["bearer", token];
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// Fallback: use the entire header value if it doesn't match expected format
|
|
187
|
+
options.protocols = [authHeader];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// Fallback for other environments
|
|
193
|
+
options.headers = headers;
|
|
194
|
+
}
|
|
195
|
+
return options;
|
|
196
|
+
}
|
|
133
197
|
/**
|
|
134
198
|
* Wrapper for Agent V1Client that overrides connect to use custom websocket.
|
|
135
199
|
*/
|
|
136
200
|
class WrappedAgentV1Client extends Client_js_4.V1Client {
|
|
137
201
|
connect() {
|
|
138
202
|
return __awaiter(this, arguments, void 0, function* (args = {}) {
|
|
139
|
-
var _a, _b, _c, _d;
|
|
203
|
+
var _a, _b, _c, _d, _e;
|
|
140
204
|
const { headers, debug, reconnectAttempts } = args;
|
|
141
205
|
// Get Authorization from authProvider (matching the working version)
|
|
142
206
|
const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
|
|
143
207
|
const _headers = (0, headers_js_1.mergeHeaders)((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
|
|
208
|
+
// Get WebSocket options with proper header handling
|
|
209
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
144
210
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
145
211
|
const socket = new ws_js_1.ReconnectingWebSocket({
|
|
146
212
|
url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).agent, "/v1/agent/converse"),
|
|
147
|
-
protocols: [],
|
|
213
|
+
protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
|
|
148
214
|
queryParameters: {},
|
|
149
|
-
headers:
|
|
215
|
+
headers: wsOptions.headers,
|
|
150
216
|
options: {
|
|
217
|
+
WebSocket: wsOptions.WebSocket,
|
|
151
218
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
152
219
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
153
220
|
startClosed: true,
|
|
@@ -203,6 +270,13 @@ class WrappedAgentV1Socket extends Socket_js_1.V1Socket {
|
|
|
203
270
|
}
|
|
204
271
|
}
|
|
205
272
|
connect() {
|
|
273
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
274
|
+
// by closing and reconnecting
|
|
275
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
276
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
277
|
+
this.socket._connectLock = false;
|
|
278
|
+
this.socket._shouldReconnect = true;
|
|
279
|
+
}
|
|
206
280
|
// Call parent connect, but then ensure our binary handler is still active
|
|
207
281
|
super.connect();
|
|
208
282
|
// Re-setup binary handling in case connect() re-registered handlers
|
|
@@ -216,7 +290,7 @@ class WrappedAgentV1Socket extends Socket_js_1.V1Socket {
|
|
|
216
290
|
class WrappedListenV1Client extends Client_js_5.V1Client {
|
|
217
291
|
connect(args) {
|
|
218
292
|
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
-
var _a, _b;
|
|
293
|
+
var _a, _b, _c;
|
|
220
294
|
// Extract all the args (same as the original implementation)
|
|
221
295
|
const { callback, callback_method: callbackMethod, channels, diarize, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, headers, debug, reconnectAttempts, } = args;
|
|
222
296
|
// Build query params (same as original)
|
|
@@ -277,13 +351,16 @@ class WrappedListenV1Client extends Client_js_5.V1Client {
|
|
|
277
351
|
// Get Authorization from authProvider (matching the working version)
|
|
278
352
|
const authRequest = yield this._options.authProvider.getAuthRequest();
|
|
279
353
|
const _headers = (0, headers_js_1.mergeHeaders)(authRequest.headers, headers);
|
|
354
|
+
// Get WebSocket options with proper header handling
|
|
355
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
280
356
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
281
357
|
const socket = new ws_js_1.ReconnectingWebSocket({
|
|
282
358
|
url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/listen"),
|
|
283
|
-
protocols: [],
|
|
359
|
+
protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
|
|
284
360
|
queryParameters: _queryParams,
|
|
285
|
-
headers:
|
|
361
|
+
headers: wsOptions.headers,
|
|
286
362
|
options: {
|
|
363
|
+
WebSocket: wsOptions.WebSocket,
|
|
287
364
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
288
365
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
289
366
|
startClosed: true,
|
|
@@ -335,6 +412,12 @@ class WrappedListenV1Socket extends Socket_js_2.V1Socket {
|
|
|
335
412
|
}
|
|
336
413
|
}
|
|
337
414
|
connect() {
|
|
415
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
416
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
417
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
418
|
+
this.socket._connectLock = false;
|
|
419
|
+
this.socket._shouldReconnect = true;
|
|
420
|
+
}
|
|
338
421
|
super.connect();
|
|
339
422
|
this.setupBinaryHandling();
|
|
340
423
|
return this;
|
|
@@ -346,7 +429,7 @@ class WrappedListenV1Socket extends Socket_js_2.V1Socket {
|
|
|
346
429
|
class WrappedListenV2Client extends Client_js_6.V2Client {
|
|
347
430
|
connect(args) {
|
|
348
431
|
return __awaiter(this, void 0, void 0, function* () {
|
|
349
|
-
var _a, _b, _c, _d;
|
|
432
|
+
var _a, _b, _c, _d, _e;
|
|
350
433
|
const { model, encoding, sample_rate: sampleRate, eager_eot_threshold: eagerEotThreshold, eot_threshold: eotThreshold, eot_timeout_ms: eotTimeoutMs, keyterm, mip_opt_out: mipOptOut, tag, headers, debug, reconnectAttempts, } = args;
|
|
351
434
|
const _queryParams = {};
|
|
352
435
|
_queryParams.model = model;
|
|
@@ -369,13 +452,16 @@ class WrappedListenV2Client extends Client_js_6.V2Client {
|
|
|
369
452
|
// Get Authorization from authProvider (matching the working version)
|
|
370
453
|
const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
|
|
371
454
|
const _headers = (0, headers_js_1.mergeHeaders)((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
|
|
455
|
+
// Get WebSocket options with proper header handling
|
|
456
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
372
457
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
373
458
|
const socket = new ws_js_1.ReconnectingWebSocket({
|
|
374
459
|
url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).production, "/v2/listen"),
|
|
375
|
-
protocols: [],
|
|
460
|
+
protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
|
|
376
461
|
queryParameters: _queryParams,
|
|
377
|
-
headers:
|
|
462
|
+
headers: wsOptions.headers,
|
|
378
463
|
options: {
|
|
464
|
+
WebSocket: wsOptions.WebSocket,
|
|
379
465
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
380
466
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
381
467
|
startClosed: true,
|
|
@@ -427,6 +513,12 @@ class WrappedListenV2Socket extends Socket_js_3.V2Socket {
|
|
|
427
513
|
}
|
|
428
514
|
}
|
|
429
515
|
connect() {
|
|
516
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
517
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
518
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
519
|
+
this.socket._connectLock = false;
|
|
520
|
+
this.socket._shouldReconnect = true;
|
|
521
|
+
}
|
|
430
522
|
super.connect();
|
|
431
523
|
this.setupBinaryHandling();
|
|
432
524
|
return this;
|
|
@@ -438,7 +530,7 @@ class WrappedListenV2Socket extends Socket_js_3.V2Socket {
|
|
|
438
530
|
class WrappedSpeakV1Client extends Client_js_7.V1Client {
|
|
439
531
|
connect(args) {
|
|
440
532
|
return __awaiter(this, void 0, void 0, function* () {
|
|
441
|
-
var _a, _b;
|
|
533
|
+
var _a, _b, _c;
|
|
442
534
|
const { encoding, mip_opt_out: mipOptOut, model, sample_rate: sampleRate, headers, debug, reconnectAttempts, } = args;
|
|
443
535
|
const _queryParams = {};
|
|
444
536
|
if (encoding != null)
|
|
@@ -452,13 +544,16 @@ class WrappedSpeakV1Client extends Client_js_7.V1Client {
|
|
|
452
544
|
// Get Authorization from authProvider (matching the working version)
|
|
453
545
|
const authRequest = yield this._options.authProvider.getAuthRequest();
|
|
454
546
|
const _headers = (0, headers_js_1.mergeHeaders)(authRequest.headers, headers);
|
|
547
|
+
// Get WebSocket options with proper header handling
|
|
548
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
455
549
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
456
550
|
const socket = new ws_js_1.ReconnectingWebSocket({
|
|
457
551
|
url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/speak"),
|
|
458
|
-
protocols: [],
|
|
552
|
+
protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
|
|
459
553
|
queryParameters: _queryParams,
|
|
460
|
-
headers:
|
|
554
|
+
headers: wsOptions.headers,
|
|
461
555
|
options: {
|
|
556
|
+
WebSocket: wsOptions.WebSocket,
|
|
462
557
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
463
558
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
464
559
|
startClosed: true,
|
|
@@ -510,6 +605,12 @@ class WrappedSpeakV1Socket extends Socket_js_4.V1Socket {
|
|
|
510
605
|
}
|
|
511
606
|
}
|
|
512
607
|
connect() {
|
|
608
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
609
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
610
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
611
|
+
this.socket._connectLock = false;
|
|
612
|
+
this.socket._shouldReconnect = true;
|
|
613
|
+
}
|
|
513
614
|
super.connect();
|
|
514
615
|
this.setupBinaryHandling();
|
|
515
616
|
return this;
|
|
@@ -39,14 +39,13 @@ const index_js_1 = require("../runtime/index.js");
|
|
|
39
39
|
const qs_js_1 = require("../url/qs.js");
|
|
40
40
|
const Events = __importStar(require("./events.js"));
|
|
41
41
|
const getGlobalWebSocket = () => {
|
|
42
|
-
|
|
43
|
-
if (index_js_1.RUNTIME.type === "node") {
|
|
44
|
-
return ws_1.WebSocket;
|
|
45
|
-
}
|
|
46
|
-
else if (typeof WebSocket !== "undefined") {
|
|
42
|
+
if (typeof WebSocket !== "undefined") {
|
|
47
43
|
// @ts-ignore
|
|
48
44
|
return WebSocket;
|
|
49
45
|
}
|
|
46
|
+
else if (index_js_1.RUNTIME.type === "node") {
|
|
47
|
+
return ws_1.WebSocket;
|
|
48
|
+
}
|
|
50
49
|
return undefined;
|
|
51
50
|
};
|
|
52
51
|
/**
|
|
@@ -122,14 +121,12 @@ class ReconnectingWebSocket {
|
|
|
122
121
|
};
|
|
123
122
|
this._handleError = (event) => {
|
|
124
123
|
this._debug("error event", event.message);
|
|
125
|
-
|
|
126
|
-
this._disconnect(1006, event.message === "TIMEOUT" ? "timeout" : undefined);
|
|
124
|
+
this._disconnect(undefined, event.message === "TIMEOUT" ? "timeout" : undefined);
|
|
127
125
|
if (this.onerror) {
|
|
128
126
|
this.onerror(event);
|
|
129
127
|
}
|
|
128
|
+
this._debug("exec error listeners");
|
|
130
129
|
this._listeners.error.forEach((listener) => this._callEventListener(event, listener));
|
|
131
|
-
// Ensure we can retry by setting _shouldReconnect to true
|
|
132
|
-
this._shouldReconnect = true;
|
|
133
130
|
this._connect();
|
|
134
131
|
};
|
|
135
132
|
this._handleClose = (event) => {
|
|
@@ -366,18 +363,7 @@ class ReconnectingWebSocket {
|
|
|
366
363
|
}
|
|
367
364
|
const options = {};
|
|
368
365
|
if (this._headers) {
|
|
369
|
-
|
|
370
|
-
const stringHeaders = {};
|
|
371
|
-
for (const [key, value] of Object.entries(this._headers)) {
|
|
372
|
-
if (typeof value === "string") {
|
|
373
|
-
stringHeaders[key] = value;
|
|
374
|
-
}
|
|
375
|
-
else if (value != null) {
|
|
376
|
-
// Convert non-string values to strings
|
|
377
|
-
stringHeaders[key] = String(value);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
options.headers = stringHeaders;
|
|
366
|
+
options.headers = this._headers;
|
|
381
367
|
}
|
|
382
368
|
if (this._queryParameters && Object.keys(this._queryParameters).length > 0) {
|
|
383
369
|
const queryString = (0, qs_js_1.toQueryString)(this._queryParameters, { arrayFormat: "repeat" });
|
|
@@ -431,14 +417,7 @@ class ReconnectingWebSocket {
|
|
|
431
417
|
this._debug("removeListeners");
|
|
432
418
|
this._ws.removeEventListener("open", this._handleOpen);
|
|
433
419
|
this._ws.removeEventListener("close", this._handleClose);
|
|
434
|
-
|
|
435
|
-
// Remove the message listener we added with .on()
|
|
436
|
-
this._ws.off("message", this._nodeMessageHandler);
|
|
437
|
-
this._nodeMessageHandler = undefined;
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
this._ws.removeEventListener("message", this._handleMessage);
|
|
441
|
-
}
|
|
420
|
+
this._ws.removeEventListener("message", this._handleMessage);
|
|
442
421
|
// @ts-ignore
|
|
443
422
|
this._ws.removeEventListener("error", this._handleError);
|
|
444
423
|
}
|
|
@@ -449,24 +428,7 @@ class ReconnectingWebSocket {
|
|
|
449
428
|
this._debug("addListeners");
|
|
450
429
|
this._ws.addEventListener("open", this._handleOpen);
|
|
451
430
|
this._ws.addEventListener("close", this._handleClose);
|
|
452
|
-
|
|
453
|
-
if (index_js_1.RUNTIME.type === "node") {
|
|
454
|
-
// ws library emits data directly via .on(), not as MessageEvent
|
|
455
|
-
// Convert Buffer to string for text messages
|
|
456
|
-
this._nodeMessageHandler = (data, isBinary) => {
|
|
457
|
-
// Convert Buffer to string if it's a text message
|
|
458
|
-
let messageData = data;
|
|
459
|
-
if (!isBinary && Buffer.isBuffer(data)) {
|
|
460
|
-
messageData = data.toString("utf8");
|
|
461
|
-
}
|
|
462
|
-
const event = { data: messageData, type: "message", target: this._ws };
|
|
463
|
-
this._handleMessage(event);
|
|
464
|
-
};
|
|
465
|
-
this._ws.on("message", this._nodeMessageHandler);
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
this._ws.addEventListener("message", this._handleMessage);
|
|
469
|
-
}
|
|
431
|
+
this._ws.addEventListener("message", this._handleMessage);
|
|
470
432
|
// @ts-ignore
|
|
471
433
|
this._ws.addEventListener("error", this._handleError);
|
|
472
434
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SDK_VERSION = "0.0.219";
|
package/dist/esm/BaseClient.mjs
CHANGED
|
@@ -5,6 +5,9 @@ import * as core from "./core/index.mjs";
|
|
|
5
5
|
export function normalizeClientOptions(options) {
|
|
6
6
|
const headers = mergeHeaders({
|
|
7
7
|
"X-Fern-Language": "JavaScript",
|
|
8
|
+
"X-Fern-SDK-Name": "",
|
|
9
|
+
"X-Fern-SDK-Version": "0.0.219",
|
|
10
|
+
"User-Agent": "/0.0.219",
|
|
8
11
|
"X-Fern-Runtime": core.RUNTIME.type,
|
|
9
12
|
"X-Fern-Runtime-Version": core.RUNTIME.version,
|
|
10
13
|
}, options === null || options === void 0 ? void 0 : options.headers);
|
|
@@ -24,6 +24,19 @@ import { mergeHeaders, mergeOnlyDefinedHeaders } from "./core/headers.mjs";
|
|
|
24
24
|
import { fromJson } from "./core/json.mjs";
|
|
25
25
|
import * as core from "./core/index.mjs";
|
|
26
26
|
import * as environments from "./environments.mjs";
|
|
27
|
+
import { RUNTIME } from "./core/runtime/index.mjs";
|
|
28
|
+
// Import ws library for Node.js (will be undefined in browser)
|
|
29
|
+
let NodeWebSocket;
|
|
30
|
+
try {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
NodeWebSocket = require("ws");
|
|
33
|
+
// Handle both default export and named export
|
|
34
|
+
NodeWebSocket = NodeWebSocket.WebSocket || NodeWebSocket.default || NodeWebSocket;
|
|
35
|
+
}
|
|
36
|
+
catch (_a) {
|
|
37
|
+
// ws not available (e.g., in browser)
|
|
38
|
+
NodeWebSocket = undefined;
|
|
39
|
+
}
|
|
27
40
|
/**
|
|
28
41
|
* Custom wrapper around DeepgramClient that ensures the custom websocket implementation
|
|
29
42
|
* from ws.ts is always used, even if the auto-generated code changes.
|
|
@@ -93,24 +106,78 @@ class WrappedSpeakClient extends SpeakClientImpl {
|
|
|
93
106
|
return new WrappedSpeakV1Client(this._options);
|
|
94
107
|
}
|
|
95
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Helper function to get WebSocket class and handle headers/protocols based on runtime.
|
|
111
|
+
* In Node.js, use the 'ws' library which supports headers.
|
|
112
|
+
* In browser, use Sec-WebSocket-Protocol for authentication since headers aren't supported.
|
|
113
|
+
*/
|
|
114
|
+
function getWebSocketOptions(headers) {
|
|
115
|
+
const options = {};
|
|
116
|
+
// Check if we're in a browser environment (browser or web-worker)
|
|
117
|
+
const isBrowser = RUNTIME.type === "browser" || RUNTIME.type === "web-worker";
|
|
118
|
+
// In Node.js, ensure we use the 'ws' library which supports headers
|
|
119
|
+
if (RUNTIME.type === "node" && NodeWebSocket) {
|
|
120
|
+
options.WebSocket = NodeWebSocket;
|
|
121
|
+
options.headers = headers;
|
|
122
|
+
}
|
|
123
|
+
else if (isBrowser) {
|
|
124
|
+
// In browser, native WebSocket doesn't support custom headers
|
|
125
|
+
// Extract Authorization header and use Sec-WebSocket-Protocol instead
|
|
126
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
127
|
+
const browserHeaders = Object.assign({}, headers);
|
|
128
|
+
// Remove Authorization from headers since it won't work in browser
|
|
129
|
+
delete browserHeaders.Authorization;
|
|
130
|
+
delete browserHeaders.authorization;
|
|
131
|
+
options.headers = browserHeaders;
|
|
132
|
+
// If we have an Authorization header, extract the token and format as protocols
|
|
133
|
+
// Deepgram expects:
|
|
134
|
+
// - For API keys: Sec-WebSocket-Protocol: token,API_KEY_GOES_HERE
|
|
135
|
+
// - For Bearer tokens: Sec-WebSocket-Protocol: bearer,TOKEN_GOES_HERE
|
|
136
|
+
// The comma separates multiple protocols, so we pass them as an array
|
|
137
|
+
if (authHeader && typeof authHeader === "string") {
|
|
138
|
+
if (authHeader.startsWith("Token ")) {
|
|
139
|
+
// API key: "Token API_KEY" -> ["token", "API_KEY"]
|
|
140
|
+
const apiKey = authHeader.substring(6); // Remove "Token " prefix
|
|
141
|
+
options.protocols = ["token", apiKey];
|
|
142
|
+
}
|
|
143
|
+
else if (authHeader.startsWith("Bearer ")) {
|
|
144
|
+
// Access token: "Bearer TOKEN" -> ["bearer", "TOKEN"]
|
|
145
|
+
const token = authHeader.substring(7); // Remove "Bearer " prefix
|
|
146
|
+
options.protocols = ["bearer", token];
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// Fallback: use the entire header value if it doesn't match expected format
|
|
150
|
+
options.protocols = [authHeader];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Fallback for other environments
|
|
156
|
+
options.headers = headers;
|
|
157
|
+
}
|
|
158
|
+
return options;
|
|
159
|
+
}
|
|
96
160
|
/**
|
|
97
161
|
* Wrapper for Agent V1Client that overrides connect to use custom websocket.
|
|
98
162
|
*/
|
|
99
163
|
class WrappedAgentV1Client extends AgentV1Client {
|
|
100
164
|
connect() {
|
|
101
165
|
return __awaiter(this, arguments, void 0, function* (args = {}) {
|
|
102
|
-
var _a, _b, _c, _d;
|
|
166
|
+
var _a, _b, _c, _d, _e;
|
|
103
167
|
const { headers, debug, reconnectAttempts } = args;
|
|
104
168
|
// Get Authorization from authProvider (matching the working version)
|
|
105
169
|
const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
|
|
106
170
|
const _headers = mergeHeaders((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
|
|
171
|
+
// Get WebSocket options with proper header handling
|
|
172
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
107
173
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
108
174
|
const socket = new ReconnectingWebSocket({
|
|
109
175
|
url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).agent, "/v1/agent/converse"),
|
|
110
|
-
protocols: [],
|
|
176
|
+
protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
|
|
111
177
|
queryParameters: {},
|
|
112
|
-
headers:
|
|
178
|
+
headers: wsOptions.headers,
|
|
113
179
|
options: {
|
|
180
|
+
WebSocket: wsOptions.WebSocket,
|
|
114
181
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
115
182
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
116
183
|
startClosed: true,
|
|
@@ -166,6 +233,13 @@ class WrappedAgentV1Socket extends AgentV1Socket {
|
|
|
166
233
|
}
|
|
167
234
|
}
|
|
168
235
|
connect() {
|
|
236
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
237
|
+
// by closing and reconnecting
|
|
238
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
239
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
240
|
+
this.socket._connectLock = false;
|
|
241
|
+
this.socket._shouldReconnect = true;
|
|
242
|
+
}
|
|
169
243
|
// Call parent connect, but then ensure our binary handler is still active
|
|
170
244
|
super.connect();
|
|
171
245
|
// Re-setup binary handling in case connect() re-registered handlers
|
|
@@ -179,7 +253,7 @@ class WrappedAgentV1Socket extends AgentV1Socket {
|
|
|
179
253
|
class WrappedListenV1Client extends ListenV1Client {
|
|
180
254
|
connect(args) {
|
|
181
255
|
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
-
var _a, _b;
|
|
256
|
+
var _a, _b, _c;
|
|
183
257
|
// Extract all the args (same as the original implementation)
|
|
184
258
|
const { callback, callback_method: callbackMethod, channels, diarize, dictation, encoding, endpointing, extra, interim_results: interimResults, keyterm, keywords, language, mip_opt_out: mipOptOut, model, multichannel, numerals, profanity_filter: profanityFilter, punctuate, redact, replace, sample_rate: sampleRate, search, smart_format: smartFormat, tag, utterance_end_ms: utteranceEndMs, vad_events: vadEvents, version, headers, debug, reconnectAttempts, } = args;
|
|
185
259
|
// Build query params (same as original)
|
|
@@ -240,13 +314,16 @@ class WrappedListenV1Client extends ListenV1Client {
|
|
|
240
314
|
// Get Authorization from authProvider (matching the working version)
|
|
241
315
|
const authRequest = yield this._options.authProvider.getAuthRequest();
|
|
242
316
|
const _headers = mergeHeaders(authRequest.headers, headers);
|
|
317
|
+
// Get WebSocket options with proper header handling
|
|
318
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
243
319
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
244
320
|
const socket = new ReconnectingWebSocket({
|
|
245
321
|
url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/listen"),
|
|
246
|
-
protocols: [],
|
|
322
|
+
protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
|
|
247
323
|
queryParameters: _queryParams,
|
|
248
|
-
headers:
|
|
324
|
+
headers: wsOptions.headers,
|
|
249
325
|
options: {
|
|
326
|
+
WebSocket: wsOptions.WebSocket,
|
|
250
327
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
251
328
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
252
329
|
startClosed: true,
|
|
@@ -298,6 +375,12 @@ class WrappedListenV1Socket extends ListenV1Socket {
|
|
|
298
375
|
}
|
|
299
376
|
}
|
|
300
377
|
connect() {
|
|
378
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
379
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
380
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
381
|
+
this.socket._connectLock = false;
|
|
382
|
+
this.socket._shouldReconnect = true;
|
|
383
|
+
}
|
|
301
384
|
super.connect();
|
|
302
385
|
this.setupBinaryHandling();
|
|
303
386
|
return this;
|
|
@@ -309,7 +392,7 @@ class WrappedListenV1Socket extends ListenV1Socket {
|
|
|
309
392
|
class WrappedListenV2Client extends ListenV2Client {
|
|
310
393
|
connect(args) {
|
|
311
394
|
return __awaiter(this, void 0, void 0, function* () {
|
|
312
|
-
var _a, _b, _c, _d;
|
|
395
|
+
var _a, _b, _c, _d, _e;
|
|
313
396
|
const { model, encoding, sample_rate: sampleRate, eager_eot_threshold: eagerEotThreshold, eot_threshold: eotThreshold, eot_timeout_ms: eotTimeoutMs, keyterm, mip_opt_out: mipOptOut, tag, headers, debug, reconnectAttempts, } = args;
|
|
314
397
|
const _queryParams = {};
|
|
315
398
|
_queryParams.model = model;
|
|
@@ -332,13 +415,16 @@ class WrappedListenV2Client extends ListenV2Client {
|
|
|
332
415
|
// Get Authorization from authProvider (matching the working version)
|
|
333
416
|
const authRequest = yield ((_a = this._options.authProvider) === null || _a === void 0 ? void 0 : _a.getAuthRequest());
|
|
334
417
|
const _headers = mergeHeaders((_b = authRequest === null || authRequest === void 0 ? void 0 : authRequest.headers) !== null && _b !== void 0 ? _b : {}, headers);
|
|
418
|
+
// Get WebSocket options with proper header handling
|
|
419
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
335
420
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
336
421
|
const socket = new ReconnectingWebSocket({
|
|
337
422
|
url: core.url.join((_c = (yield core.Supplier.get(this._options.baseUrl))) !== null && _c !== void 0 ? _c : ((_d = (yield core.Supplier.get(this._options.environment))) !== null && _d !== void 0 ? _d : environments.DeepgramEnvironment.Production).production, "/v2/listen"),
|
|
338
|
-
protocols: [],
|
|
423
|
+
protocols: (_e = wsOptions.protocols) !== null && _e !== void 0 ? _e : [],
|
|
339
424
|
queryParameters: _queryParams,
|
|
340
|
-
headers:
|
|
425
|
+
headers: wsOptions.headers,
|
|
341
426
|
options: {
|
|
427
|
+
WebSocket: wsOptions.WebSocket,
|
|
342
428
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
343
429
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
344
430
|
startClosed: true,
|
|
@@ -390,6 +476,12 @@ class WrappedListenV2Socket extends ListenV2Socket {
|
|
|
390
476
|
}
|
|
391
477
|
}
|
|
392
478
|
connect() {
|
|
479
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
480
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
481
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
482
|
+
this.socket._connectLock = false;
|
|
483
|
+
this.socket._shouldReconnect = true;
|
|
484
|
+
}
|
|
393
485
|
super.connect();
|
|
394
486
|
this.setupBinaryHandling();
|
|
395
487
|
return this;
|
|
@@ -401,7 +493,7 @@ class WrappedListenV2Socket extends ListenV2Socket {
|
|
|
401
493
|
class WrappedSpeakV1Client extends SpeakV1Client {
|
|
402
494
|
connect(args) {
|
|
403
495
|
return __awaiter(this, void 0, void 0, function* () {
|
|
404
|
-
var _a, _b;
|
|
496
|
+
var _a, _b, _c;
|
|
405
497
|
const { encoding, mip_opt_out: mipOptOut, model, sample_rate: sampleRate, headers, debug, reconnectAttempts, } = args;
|
|
406
498
|
const _queryParams = {};
|
|
407
499
|
if (encoding != null)
|
|
@@ -415,13 +507,16 @@ class WrappedSpeakV1Client extends SpeakV1Client {
|
|
|
415
507
|
// Get Authorization from authProvider (matching the working version)
|
|
416
508
|
const authRequest = yield this._options.authProvider.getAuthRequest();
|
|
417
509
|
const _headers = mergeHeaders(authRequest.headers, headers);
|
|
510
|
+
// Get WebSocket options with proper header handling
|
|
511
|
+
const wsOptions = getWebSocketOptions(_headers);
|
|
418
512
|
// Explicitly use the custom ReconnectingWebSocket from ws.ts
|
|
419
513
|
const socket = new ReconnectingWebSocket({
|
|
420
514
|
url: core.url.join((_a = (yield core.Supplier.get(this._options.baseUrl))) !== null && _a !== void 0 ? _a : ((_b = (yield core.Supplier.get(this._options.environment))) !== null && _b !== void 0 ? _b : environments.DeepgramEnvironment.Production).production, "/v1/speak"),
|
|
421
|
-
protocols: [],
|
|
515
|
+
protocols: (_c = wsOptions.protocols) !== null && _c !== void 0 ? _c : [],
|
|
422
516
|
queryParameters: _queryParams,
|
|
423
|
-
headers:
|
|
517
|
+
headers: wsOptions.headers,
|
|
424
518
|
options: {
|
|
519
|
+
WebSocket: wsOptions.WebSocket,
|
|
425
520
|
debug: debug !== null && debug !== void 0 ? debug : false,
|
|
426
521
|
maxRetries: reconnectAttempts !== null && reconnectAttempts !== void 0 ? reconnectAttempts : 30,
|
|
427
522
|
startClosed: true,
|
|
@@ -473,6 +568,12 @@ class WrappedSpeakV1Socket extends SpeakV1Socket {
|
|
|
473
568
|
}
|
|
474
569
|
}
|
|
475
570
|
connect() {
|
|
571
|
+
// Ensure socket is ready to connect - if _connectLock is stuck, force reconnect
|
|
572
|
+
if (this.socket.readyState === this.socket.CLOSED) {
|
|
573
|
+
// Force a fresh reconnect to ensure _connectLock is reset
|
|
574
|
+
this.socket._connectLock = false;
|
|
575
|
+
this.socket._shouldReconnect = true;
|
|
576
|
+
}
|
|
476
577
|
super.connect();
|
|
477
578
|
this.setupBinaryHandling();
|
|
478
579
|
return this;
|