@voice-ai-labs/web-sdk 0.9.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +156 -24
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +6 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/base.d.ts +8 -2
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +31 -13
- package/dist/client/base.js.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/managed-tools.d.ts +17 -0
- package/dist/client/managed-tools.d.ts.map +1 -0
- package/dist/client/managed-tools.js +24 -0
- package/dist/client/managed-tools.js.map +1 -0
- package/dist/client/tts.d.ts +1 -1
- package/dist/client/tts.js +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +781 -46
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +798 -45
- package/dist/index.js.map +1 -1
- package/dist/managed-tools/google.d.ts +29 -0
- package/dist/managed-tools/google.d.ts.map +1 -0
- package/dist/managed-tools/google.js +178 -0
- package/dist/managed-tools/google.js.map +1 -0
- package/dist/managed-tools/iana-timezones.d.ts +10 -0
- package/dist/managed-tools/iana-timezones.d.ts.map +1 -0
- package/dist/managed-tools/iana-timezones.js +470 -0
- package/dist/managed-tools/iana-timezones.js.map +1 -0
- package/dist/types.d.ts +78 -10
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -10702,7 +10702,7 @@ function getMatch(exp, ua) {
|
|
|
10702
10702
|
}
|
|
10703
10703
|
function getOSVersion(ua) {
|
|
10704
10704
|
return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
|
|
10705
|
-
}var version$1 = "2.
|
|
10705
|
+
}var version$1 = "2.18.0";const version = version$1;
|
|
10706
10706
|
const protocolVersion = 16;/** Base error that all LiveKit specific custom errors inherit from. */
|
|
10707
10707
|
class LivekitError extends Error {
|
|
10708
10708
|
constructor(code, message, options) {
|
|
@@ -18655,6 +18655,9 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
18655
18655
|
get isClosed() {
|
|
18656
18656
|
return this._isClosed;
|
|
18657
18657
|
}
|
|
18658
|
+
get isNewlyCreated() {
|
|
18659
|
+
return this._isNewlyCreated;
|
|
18660
|
+
}
|
|
18658
18661
|
get pendingReconnect() {
|
|
18659
18662
|
return !!this.reconnectTimeout;
|
|
18660
18663
|
}
|
|
@@ -18672,6 +18675,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
18672
18675
|
this.subscriberPrimary = false;
|
|
18673
18676
|
this.pcState = PCState.New;
|
|
18674
18677
|
this._isClosed = true;
|
|
18678
|
+
this._isNewlyCreated = true;
|
|
18675
18679
|
this.pendingTrackResolvers = {};
|
|
18676
18680
|
this.reconnectAttempts = 0;
|
|
18677
18681
|
this.reconnectStart = 0;
|
|
@@ -18929,7 +18933,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
18929
18933
|
room: (_b = (_a = this.latestJoinResponse) === null || _a === void 0 ? void 0 : _a.room) === null || _b === void 0 ? void 0 : _b.name,
|
|
18930
18934
|
roomID: (_d = (_c = this.latestJoinResponse) === null || _c === void 0 ? void 0 : _c.room) === null || _d === void 0 ? void 0 : _d.sid,
|
|
18931
18935
|
participant: (_f = (_e = this.latestJoinResponse) === null || _e === void 0 ? void 0 : _e.participant) === null || _f === void 0 ? void 0 : _f.identity,
|
|
18932
|
-
|
|
18936
|
+
participantID: this.participantSid
|
|
18933
18937
|
};
|
|
18934
18938
|
}
|
|
18935
18939
|
join(url_1, token_1, opts_1, abortSignal_1) {
|
|
@@ -18937,6 +18941,7 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
18937
18941
|
var _this2 = this;
|
|
18938
18942
|
let useV0Path = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
18939
18943
|
return function* () {
|
|
18944
|
+
_this2._isNewlyCreated = false;
|
|
18940
18945
|
_this2.url = url;
|
|
18941
18946
|
_this2.token = token;
|
|
18942
18947
|
_this2.signalOpts = opts;
|
|
@@ -20592,7 +20597,7 @@ class OutgoingDataStreamManager {
|
|
|
20592
20597
|
mimeType: info.mimeType,
|
|
20593
20598
|
topic: info.topic,
|
|
20594
20599
|
timestamp: numberToBigInt(info.timestamp),
|
|
20595
|
-
totalLength: numberToBigInt(
|
|
20600
|
+
totalLength: numberToBigInt(info.size),
|
|
20596
20601
|
attributes: info.attributes,
|
|
20597
20602
|
contentHeader: {
|
|
20598
20603
|
case: 'textHeader',
|
|
@@ -20702,7 +20707,7 @@ class OutgoingDataStreamManager {
|
|
|
20702
20707
|
}
|
|
20703
20708
|
streamBytes(options) {
|
|
20704
20709
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20705
|
-
var _a, _b, _c, _d, _e
|
|
20710
|
+
var _a, _b, _c, _d, _e;
|
|
20706
20711
|
const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
|
|
20707
20712
|
const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
|
|
20708
20713
|
const info = {
|
|
@@ -20716,7 +20721,7 @@ class OutgoingDataStreamManager {
|
|
|
20716
20721
|
encryptionType: ((_e = this.engine.e2eeManager) === null || _e === void 0 ? void 0 : _e.isDataChannelEncryptionEnabled) ? Encryption_Type.GCM : Encryption_Type.NONE
|
|
20717
20722
|
};
|
|
20718
20723
|
const header = new DataStream_Header({
|
|
20719
|
-
totalLength: numberToBigInt(
|
|
20724
|
+
totalLength: numberToBigInt(info.size),
|
|
20720
20725
|
mimeType: info.mimeType,
|
|
20721
20726
|
streamId,
|
|
20722
20727
|
topic: info.topic,
|
|
@@ -24089,7 +24094,7 @@ class Participant extends eventsExports.EventEmitter {
|
|
|
24089
24094
|
}
|
|
24090
24095
|
get logContext() {
|
|
24091
24096
|
return Object.assign(Object.assign({}, super.logContext), {
|
|
24092
|
-
|
|
24097
|
+
remoteParticipantID: this.sid,
|
|
24093
24098
|
remoteParticipant: this.identity
|
|
24094
24099
|
});
|
|
24095
24100
|
}
|
|
@@ -25245,7 +25250,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
25245
25250
|
room: this.name,
|
|
25246
25251
|
roomID: (_a = this.roomInfo) === null || _a === void 0 ? void 0 : _a.sid,
|
|
25247
25252
|
participant: this.localParticipant.identity,
|
|
25248
|
-
|
|
25253
|
+
participantID: this.localParticipant.sid
|
|
25249
25254
|
};
|
|
25250
25255
|
}
|
|
25251
25256
|
/**
|
|
@@ -25299,7 +25304,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
25299
25304
|
return (_b = (_a = this.roomInfo) === null || _a === void 0 ? void 0 : _a.numPublishers) !== null && _b !== void 0 ? _b : 0;
|
|
25300
25305
|
}
|
|
25301
25306
|
maybeCreateEngine() {
|
|
25302
|
-
if (this.engine && !this.engine.isClosed) {
|
|
25307
|
+
if (this.engine && (this.engine.isNewlyCreated || !this.engine.isClosed)) {
|
|
25303
25308
|
return;
|
|
25304
25309
|
}
|
|
25305
25310
|
this.engine = new RTCEngine(this.options);
|
|
@@ -25752,7 +25757,7 @@ class Room extends eventsExports.EventEmitter {
|
|
|
25752
25757
|
}
|
|
25753
25758
|
if (!trackId.startsWith('TR')) {
|
|
25754
25759
|
this.log.warn("Tried to add a track whose 'sid' could not be determined for a participant, that's not present. Sid: ".concat(participantSid, ", streamId: ").concat(streamId, ", trackId: ").concat(trackId), Object.assign(Object.assign({}, this.logContext), {
|
|
25755
|
-
|
|
25760
|
+
remoteParticipantID: participantSid,
|
|
25756
25761
|
streamId,
|
|
25757
25762
|
trackId
|
|
25758
25763
|
}));
|
|
@@ -26295,6 +26300,11 @@ function mapArgs(args) {
|
|
|
26295
26300
|
return arg;
|
|
26296
26301
|
});
|
|
26297
26302
|
}// This file was generated from JSON Schema using quicktype, do not modify it directly.
|
|
26303
|
+
var DataTrackHandleErrorReason;
|
|
26304
|
+
(function (DataTrackHandleErrorReason) {
|
|
26305
|
+
DataTrackHandleErrorReason[DataTrackHandleErrorReason["Reserved"] = 0] = "Reserved";
|
|
26306
|
+
DataTrackHandleErrorReason[DataTrackHandleErrorReason["TooLarge"] = 1] = "TooLarge";
|
|
26307
|
+
})(DataTrackHandleErrorReason || (DataTrackHandleErrorReason = {}));
|
|
26298
26308
|
var DataTrackDeserializeErrorReason;
|
|
26299
26309
|
(function (DataTrackDeserializeErrorReason) {
|
|
26300
26310
|
DataTrackDeserializeErrorReason[DataTrackDeserializeErrorReason["TooShort"] = 0] = "TooShort";
|
|
@@ -26316,11 +26326,6 @@ var DataTrackExtensionTag;
|
|
|
26316
26326
|
})(DataTrackExtensionTag || (DataTrackExtensionTag = {}));
|
|
26317
26327
|
DataTrackExtensionTag.UserTimestamp;
|
|
26318
26328
|
DataTrackExtensionTag.E2ee;
|
|
26319
|
-
var DataTrackHandleErrorReason;
|
|
26320
|
-
(function (DataTrackHandleErrorReason) {
|
|
26321
|
-
DataTrackHandleErrorReason[DataTrackHandleErrorReason["Reserved"] = 0] = "Reserved";
|
|
26322
|
-
DataTrackHandleErrorReason[DataTrackHandleErrorReason["TooLarge"] = 1] = "TooLarge";
|
|
26323
|
-
})(DataTrackHandleErrorReason || (DataTrackHandleErrorReason = {}));
|
|
26324
26329
|
/** Marker indicating a packet's position in relation to a frame. */
|
|
26325
26330
|
var FrameMarker;
|
|
26326
26331
|
(function (FrameMarker) {
|
|
@@ -26344,7 +26349,17 @@ var DataTrackDepacketizerDropReason;
|
|
|
26344
26349
|
DataTrackDepacketizerDropReason[DataTrackDepacketizerDropReason["UnknownFrame"] = 1] = "UnknownFrame";
|
|
26345
26350
|
DataTrackDepacketizerDropReason[DataTrackDepacketizerDropReason["BufferFull"] = 2] = "BufferFull";
|
|
26346
26351
|
DataTrackDepacketizerDropReason[DataTrackDepacketizerDropReason["Incomplete"] = 3] = "Incomplete";
|
|
26347
|
-
})(DataTrackDepacketizerDropReason || (DataTrackDepacketizerDropReason = {}));var
|
|
26352
|
+
})(DataTrackDepacketizerDropReason || (DataTrackDepacketizerDropReason = {}));var DataTrackSubscribeErrorReason;
|
|
26353
|
+
(function (DataTrackSubscribeErrorReason) {
|
|
26354
|
+
/** The track has been unpublished and is no longer available */
|
|
26355
|
+
DataTrackSubscribeErrorReason[DataTrackSubscribeErrorReason["Unpublished"] = 0] = "Unpublished";
|
|
26356
|
+
/** Request to subscribe to data track timed-out */
|
|
26357
|
+
DataTrackSubscribeErrorReason[DataTrackSubscribeErrorReason["Timeout"] = 1] = "Timeout";
|
|
26358
|
+
/** Cannot subscribe to data track when disconnected */
|
|
26359
|
+
DataTrackSubscribeErrorReason[DataTrackSubscribeErrorReason["Disconnected"] = 2] = "Disconnected";
|
|
26360
|
+
/** Subscription to data track cancelled by caller */
|
|
26361
|
+
DataTrackSubscribeErrorReason[DataTrackSubscribeErrorReason["Cancelled"] = 4] = "Cancelled";
|
|
26362
|
+
})(DataTrackSubscribeErrorReason || (DataTrackSubscribeErrorReason = {}));getLogger(LoggerNames.DataTracks);getLogger(LoggerNames.DataTracks);var DataTrackPublishErrorReason;
|
|
26348
26363
|
(function (DataTrackPublishErrorReason) {
|
|
26349
26364
|
/**
|
|
26350
26365
|
* Local participant does not have permission to publish data tracks.
|
|
@@ -27320,15 +27335,33 @@ class VoiceAIError extends Error {
|
|
|
27320
27335
|
*/
|
|
27321
27336
|
class BaseClient {
|
|
27322
27337
|
constructor(config) {
|
|
27323
|
-
this.apiKey = config.apiKey;
|
|
27338
|
+
this.apiKey = config.apiKey || '';
|
|
27339
|
+
this.authToken = config.authToken;
|
|
27340
|
+
this.getAuthToken = config.getAuthToken;
|
|
27324
27341
|
this.apiUrl = config.apiUrl;
|
|
27325
27342
|
}
|
|
27343
|
+
async resolveBearerToken() {
|
|
27344
|
+
if (this.apiKey) {
|
|
27345
|
+
return this.apiKey;
|
|
27346
|
+
}
|
|
27347
|
+
if (this.authToken) {
|
|
27348
|
+
return this.authToken;
|
|
27349
|
+
}
|
|
27350
|
+
if (this.getAuthToken) {
|
|
27351
|
+
const resolvedToken = await this.getAuthToken();
|
|
27352
|
+
if (typeof resolvedToken === 'string' && resolvedToken.trim()) {
|
|
27353
|
+
return resolvedToken;
|
|
27354
|
+
}
|
|
27355
|
+
}
|
|
27356
|
+
throw new VoiceAIError('Authentication required. Configure apiKey, authToken, or getAuthToken.', 401, 'UNAUTHORIZED');
|
|
27357
|
+
}
|
|
27326
27358
|
/**
|
|
27327
27359
|
* Build headers with authentication
|
|
27328
27360
|
*/
|
|
27329
|
-
getHeaders(contentType = 'application/json') {
|
|
27361
|
+
async getHeaders(contentType = 'application/json') {
|
|
27362
|
+
const bearerToken = await this.resolveBearerToken();
|
|
27330
27363
|
const headers = {
|
|
27331
|
-
'Authorization': `Bearer ${
|
|
27364
|
+
'Authorization': `Bearer ${bearerToken}`,
|
|
27332
27365
|
};
|
|
27333
27366
|
if (contentType) {
|
|
27334
27367
|
headers['Content-Type'] = contentType;
|
|
@@ -27358,7 +27391,7 @@ class BaseClient {
|
|
|
27358
27391
|
}
|
|
27359
27392
|
// Handle specific error codes
|
|
27360
27393
|
if (response.status === 401) {
|
|
27361
|
-
throw new VoiceAIError('Authentication failed. Please check your API key.', 401, 'UNAUTHORIZED');
|
|
27394
|
+
throw new VoiceAIError('Authentication failed. Please check your API key or auth token.', 401, 'UNAUTHORIZED');
|
|
27362
27395
|
}
|
|
27363
27396
|
if (response.status === 403) {
|
|
27364
27397
|
const detail = errorData?.detail || errorData?.error;
|
|
@@ -27399,7 +27432,7 @@ class BaseClient {
|
|
|
27399
27432
|
}
|
|
27400
27433
|
const response = await fetch(url.toString(), {
|
|
27401
27434
|
method: 'GET',
|
|
27402
|
-
headers: this.getHeaders(),
|
|
27435
|
+
headers: await this.getHeaders(),
|
|
27403
27436
|
});
|
|
27404
27437
|
return this.handleResponse(response);
|
|
27405
27438
|
}
|
|
@@ -27422,7 +27455,7 @@ class BaseClient {
|
|
|
27422
27455
|
}
|
|
27423
27456
|
const response = await fetch(url.toString(), {
|
|
27424
27457
|
method: 'GET',
|
|
27425
|
-
headers: this.getHeaders(),
|
|
27458
|
+
headers: await this.getHeaders(),
|
|
27426
27459
|
});
|
|
27427
27460
|
if (!response.ok) {
|
|
27428
27461
|
let errorData = null;
|
|
@@ -27442,7 +27475,7 @@ class BaseClient {
|
|
|
27442
27475
|
async post(path, body) {
|
|
27443
27476
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27444
27477
|
method: 'POST',
|
|
27445
|
-
headers: this.getHeaders(),
|
|
27478
|
+
headers: await this.getHeaders(),
|
|
27446
27479
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
27447
27480
|
});
|
|
27448
27481
|
return this.handleResponse(response);
|
|
@@ -27453,7 +27486,7 @@ class BaseClient {
|
|
|
27453
27486
|
async postFormData(path, formData) {
|
|
27454
27487
|
// Don't set Content-Type header - browser will set it with boundary
|
|
27455
27488
|
const headers = {
|
|
27456
|
-
'Authorization': `Bearer ${this.
|
|
27489
|
+
'Authorization': `Bearer ${await this.resolveBearerToken()}`,
|
|
27457
27490
|
};
|
|
27458
27491
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27459
27492
|
method: 'POST',
|
|
@@ -27468,7 +27501,7 @@ class BaseClient {
|
|
|
27468
27501
|
async put(path, body) {
|
|
27469
27502
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27470
27503
|
method: 'PUT',
|
|
27471
|
-
headers: this.getHeaders(),
|
|
27504
|
+
headers: await this.getHeaders(),
|
|
27472
27505
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
27473
27506
|
});
|
|
27474
27507
|
return this.handleResponse(response);
|
|
@@ -27479,7 +27512,7 @@ class BaseClient {
|
|
|
27479
27512
|
async patch(path, body) {
|
|
27480
27513
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27481
27514
|
method: 'PATCH',
|
|
27482
|
-
headers: this.getHeaders(),
|
|
27515
|
+
headers: await this.getHeaders(),
|
|
27483
27516
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
27484
27517
|
});
|
|
27485
27518
|
return this.handleResponse(response);
|
|
@@ -27490,7 +27523,7 @@ class BaseClient {
|
|
|
27490
27523
|
async httpDelete(path) {
|
|
27491
27524
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27492
27525
|
method: 'DELETE',
|
|
27493
|
-
headers: this.getHeaders(),
|
|
27526
|
+
headers: await this.getHeaders(),
|
|
27494
27527
|
});
|
|
27495
27528
|
return this.handleResponse(response);
|
|
27496
27529
|
}
|
|
@@ -27500,7 +27533,7 @@ class BaseClient {
|
|
|
27500
27533
|
async postForBlob(path, body) {
|
|
27501
27534
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27502
27535
|
method: 'POST',
|
|
27503
|
-
headers: this.getHeaders(),
|
|
27536
|
+
headers: await this.getHeaders(),
|
|
27504
27537
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
27505
27538
|
});
|
|
27506
27539
|
if (!response.ok) {
|
|
@@ -27522,7 +27555,7 @@ class BaseClient {
|
|
|
27522
27555
|
async postForStream(path, body) {
|
|
27523
27556
|
const response = await fetch(`${this.apiUrl}${path}`, {
|
|
27524
27557
|
method: 'POST',
|
|
27525
|
-
headers: this.getHeaders(),
|
|
27558
|
+
headers: await this.getHeaders(),
|
|
27526
27559
|
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
27527
27560
|
});
|
|
27528
27561
|
if (!response.ok) {
|
|
@@ -27838,6 +27871,12 @@ class AnalyticsClient extends BaseClient {
|
|
|
27838
27871
|
params.end_date = options.end_date;
|
|
27839
27872
|
if (options?.agent_ids)
|
|
27840
27873
|
params.agent_ids = options.agent_ids;
|
|
27874
|
+
if (options?.agent_name)
|
|
27875
|
+
params.agent_name = options.agent_name;
|
|
27876
|
+
if (options?.sort_by)
|
|
27877
|
+
params.sort_by = options.sort_by;
|
|
27878
|
+
if (options?.sort_dir)
|
|
27879
|
+
params.sort_dir = options.sort_dir;
|
|
27841
27880
|
return this.get('/agent/call-history', params);
|
|
27842
27881
|
}
|
|
27843
27882
|
/**
|
|
@@ -28019,6 +28058,29 @@ class KnowledgeBaseClient extends BaseClient {
|
|
|
28019
28058
|
}
|
|
28020
28059
|
}
|
|
28021
28060
|
|
|
28061
|
+
class GoogleManagedToolsClient extends BaseClient {
|
|
28062
|
+
constructor(config) {
|
|
28063
|
+
super(config);
|
|
28064
|
+
}
|
|
28065
|
+
async startOAuth(agentId, options = {}) {
|
|
28066
|
+
return this.post(`/google/${encodeURIComponent(agentId)}/oauth/start`, {
|
|
28067
|
+
return_path: options.returnUrl,
|
|
28068
|
+
managed_tools: options.managedTools,
|
|
28069
|
+
});
|
|
28070
|
+
}
|
|
28071
|
+
async getStatus(agentId) {
|
|
28072
|
+
return this.get(`/google/${encodeURIComponent(agentId)}/status`);
|
|
28073
|
+
}
|
|
28074
|
+
async disconnect(agentId) {
|
|
28075
|
+
return this.httpDelete(`/google/${encodeURIComponent(agentId)}/disconnect`);
|
|
28076
|
+
}
|
|
28077
|
+
}
|
|
28078
|
+
class ManagedToolsClient {
|
|
28079
|
+
constructor(config) {
|
|
28080
|
+
this.google = new GoogleManagedToolsClient(config);
|
|
28081
|
+
}
|
|
28082
|
+
}
|
|
28083
|
+
|
|
28022
28084
|
/**
|
|
28023
28085
|
* Phone Number Management Client
|
|
28024
28086
|
*
|
|
@@ -28325,7 +28387,7 @@ class TTSClient extends BaseClient {
|
|
|
28325
28387
|
/**
|
|
28326
28388
|
* Clone a voice from a reference audio file
|
|
28327
28389
|
*
|
|
28328
|
-
* Accepts an audio file (MP3, WAV, or
|
|
28390
|
+
* Accepts an audio file (MP3, WAV, or M4A, max 7.5MB) and creates
|
|
28329
28391
|
* a cloned voice. The voice starts in PENDING status and moves to
|
|
28330
28392
|
* PROCESSING, then AVAILABLE once ready.
|
|
28331
28393
|
*
|
|
@@ -28458,6 +28520,648 @@ class TTSClient extends BaseClient {
|
|
|
28458
28520
|
}
|
|
28459
28521
|
}
|
|
28460
28522
|
|
|
28523
|
+
const IANA_TIMEZONE_IDS = Object.freeze([
|
|
28524
|
+
"Africa/Abidjan",
|
|
28525
|
+
"Africa/Accra",
|
|
28526
|
+
"Africa/Addis_Ababa",
|
|
28527
|
+
"Africa/Algiers",
|
|
28528
|
+
"Africa/Asmera",
|
|
28529
|
+
"Africa/Bamako",
|
|
28530
|
+
"Africa/Bangui",
|
|
28531
|
+
"Africa/Banjul",
|
|
28532
|
+
"Africa/Bissau",
|
|
28533
|
+
"Africa/Blantyre",
|
|
28534
|
+
"Africa/Brazzaville",
|
|
28535
|
+
"Africa/Bujumbura",
|
|
28536
|
+
"Africa/Cairo",
|
|
28537
|
+
"Africa/Casablanca",
|
|
28538
|
+
"Africa/Ceuta",
|
|
28539
|
+
"Africa/Conakry",
|
|
28540
|
+
"Africa/Dakar",
|
|
28541
|
+
"Africa/Dar_es_Salaam",
|
|
28542
|
+
"Africa/Djibouti",
|
|
28543
|
+
"Africa/Douala",
|
|
28544
|
+
"Africa/El_Aaiun",
|
|
28545
|
+
"Africa/Freetown",
|
|
28546
|
+
"Africa/Gaborone",
|
|
28547
|
+
"Africa/Harare",
|
|
28548
|
+
"Africa/Johannesburg",
|
|
28549
|
+
"Africa/Juba",
|
|
28550
|
+
"Africa/Kampala",
|
|
28551
|
+
"Africa/Khartoum",
|
|
28552
|
+
"Africa/Kigali",
|
|
28553
|
+
"Africa/Kinshasa",
|
|
28554
|
+
"Africa/Lagos",
|
|
28555
|
+
"Africa/Libreville",
|
|
28556
|
+
"Africa/Lome",
|
|
28557
|
+
"Africa/Luanda",
|
|
28558
|
+
"Africa/Lubumbashi",
|
|
28559
|
+
"Africa/Lusaka",
|
|
28560
|
+
"Africa/Malabo",
|
|
28561
|
+
"Africa/Maputo",
|
|
28562
|
+
"Africa/Maseru",
|
|
28563
|
+
"Africa/Mbabane",
|
|
28564
|
+
"Africa/Mogadishu",
|
|
28565
|
+
"Africa/Monrovia",
|
|
28566
|
+
"Africa/Nairobi",
|
|
28567
|
+
"Africa/Ndjamena",
|
|
28568
|
+
"Africa/Niamey",
|
|
28569
|
+
"Africa/Nouakchott",
|
|
28570
|
+
"Africa/Ouagadougou",
|
|
28571
|
+
"Africa/Porto-Novo",
|
|
28572
|
+
"Africa/Sao_Tome",
|
|
28573
|
+
"Africa/Tripoli",
|
|
28574
|
+
"Africa/Tunis",
|
|
28575
|
+
"Africa/Windhoek",
|
|
28576
|
+
"America/Adak",
|
|
28577
|
+
"America/Anchorage",
|
|
28578
|
+
"America/Anguilla",
|
|
28579
|
+
"America/Antigua",
|
|
28580
|
+
"America/Araguaina",
|
|
28581
|
+
"America/Argentina/La_Rioja",
|
|
28582
|
+
"America/Argentina/Rio_Gallegos",
|
|
28583
|
+
"America/Argentina/Salta",
|
|
28584
|
+
"America/Argentina/San_Juan",
|
|
28585
|
+
"America/Argentina/San_Luis",
|
|
28586
|
+
"America/Argentina/Tucuman",
|
|
28587
|
+
"America/Argentina/Ushuaia",
|
|
28588
|
+
"America/Aruba",
|
|
28589
|
+
"America/Asuncion",
|
|
28590
|
+
"America/Bahia",
|
|
28591
|
+
"America/Bahia_Banderas",
|
|
28592
|
+
"America/Barbados",
|
|
28593
|
+
"America/Belem",
|
|
28594
|
+
"America/Belize",
|
|
28595
|
+
"America/Blanc-Sablon",
|
|
28596
|
+
"America/Boa_Vista",
|
|
28597
|
+
"America/Bogota",
|
|
28598
|
+
"America/Boise",
|
|
28599
|
+
"America/Buenos_Aires",
|
|
28600
|
+
"America/Cambridge_Bay",
|
|
28601
|
+
"America/Campo_Grande",
|
|
28602
|
+
"America/Cancun",
|
|
28603
|
+
"America/Caracas",
|
|
28604
|
+
"America/Catamarca",
|
|
28605
|
+
"America/Cayenne",
|
|
28606
|
+
"America/Cayman",
|
|
28607
|
+
"America/Chicago",
|
|
28608
|
+
"America/Chihuahua",
|
|
28609
|
+
"America/Ciudad_Juarez",
|
|
28610
|
+
"America/Coral_Harbour",
|
|
28611
|
+
"America/Cordoba",
|
|
28612
|
+
"America/Costa_Rica",
|
|
28613
|
+
"America/Creston",
|
|
28614
|
+
"America/Cuiaba",
|
|
28615
|
+
"America/Curacao",
|
|
28616
|
+
"America/Danmarkshavn",
|
|
28617
|
+
"America/Dawson",
|
|
28618
|
+
"America/Dawson_Creek",
|
|
28619
|
+
"America/Denver",
|
|
28620
|
+
"America/Detroit",
|
|
28621
|
+
"America/Dominica",
|
|
28622
|
+
"America/Edmonton",
|
|
28623
|
+
"America/Eirunepe",
|
|
28624
|
+
"America/El_Salvador",
|
|
28625
|
+
"America/Fort_Nelson",
|
|
28626
|
+
"America/Fortaleza",
|
|
28627
|
+
"America/Glace_Bay",
|
|
28628
|
+
"America/Godthab",
|
|
28629
|
+
"America/Goose_Bay",
|
|
28630
|
+
"America/Grand_Turk",
|
|
28631
|
+
"America/Grenada",
|
|
28632
|
+
"America/Guadeloupe",
|
|
28633
|
+
"America/Guatemala",
|
|
28634
|
+
"America/Guayaquil",
|
|
28635
|
+
"America/Guyana",
|
|
28636
|
+
"America/Halifax",
|
|
28637
|
+
"America/Havana",
|
|
28638
|
+
"America/Hermosillo",
|
|
28639
|
+
"America/Indiana/Knox",
|
|
28640
|
+
"America/Indiana/Marengo",
|
|
28641
|
+
"America/Indiana/Petersburg",
|
|
28642
|
+
"America/Indiana/Tell_City",
|
|
28643
|
+
"America/Indiana/Vevay",
|
|
28644
|
+
"America/Indiana/Vincennes",
|
|
28645
|
+
"America/Indiana/Winamac",
|
|
28646
|
+
"America/Indianapolis",
|
|
28647
|
+
"America/Inuvik",
|
|
28648
|
+
"America/Iqaluit",
|
|
28649
|
+
"America/Jamaica",
|
|
28650
|
+
"America/Jujuy",
|
|
28651
|
+
"America/Juneau",
|
|
28652
|
+
"America/Kentucky/Monticello",
|
|
28653
|
+
"America/Kralendijk",
|
|
28654
|
+
"America/La_Paz",
|
|
28655
|
+
"America/Lima",
|
|
28656
|
+
"America/Los_Angeles",
|
|
28657
|
+
"America/Louisville",
|
|
28658
|
+
"America/Lower_Princes",
|
|
28659
|
+
"America/Maceio",
|
|
28660
|
+
"America/Managua",
|
|
28661
|
+
"America/Manaus",
|
|
28662
|
+
"America/Marigot",
|
|
28663
|
+
"America/Martinique",
|
|
28664
|
+
"America/Matamoros",
|
|
28665
|
+
"America/Mazatlan",
|
|
28666
|
+
"America/Mendoza",
|
|
28667
|
+
"America/Menominee",
|
|
28668
|
+
"America/Merida",
|
|
28669
|
+
"America/Metlakatla",
|
|
28670
|
+
"America/Mexico_City",
|
|
28671
|
+
"America/Miquelon",
|
|
28672
|
+
"America/Moncton",
|
|
28673
|
+
"America/Monterrey",
|
|
28674
|
+
"America/Montevideo",
|
|
28675
|
+
"America/Montserrat",
|
|
28676
|
+
"America/Nassau",
|
|
28677
|
+
"America/New_York",
|
|
28678
|
+
"America/Nome",
|
|
28679
|
+
"America/Noronha",
|
|
28680
|
+
"America/North_Dakota/Beulah",
|
|
28681
|
+
"America/North_Dakota/Center",
|
|
28682
|
+
"America/North_Dakota/New_Salem",
|
|
28683
|
+
"America/Ojinaga",
|
|
28684
|
+
"America/Panama",
|
|
28685
|
+
"America/Paramaribo",
|
|
28686
|
+
"America/Phoenix",
|
|
28687
|
+
"America/Port-au-Prince",
|
|
28688
|
+
"America/Port_of_Spain",
|
|
28689
|
+
"America/Porto_Velho",
|
|
28690
|
+
"America/Puerto_Rico",
|
|
28691
|
+
"America/Punta_Arenas",
|
|
28692
|
+
"America/Rankin_Inlet",
|
|
28693
|
+
"America/Recife",
|
|
28694
|
+
"America/Regina",
|
|
28695
|
+
"America/Resolute",
|
|
28696
|
+
"America/Rio_Branco",
|
|
28697
|
+
"America/Santarem",
|
|
28698
|
+
"America/Santiago",
|
|
28699
|
+
"America/Santo_Domingo",
|
|
28700
|
+
"America/Sao_Paulo",
|
|
28701
|
+
"America/Scoresbysund",
|
|
28702
|
+
"America/Sitka",
|
|
28703
|
+
"America/St_Barthelemy",
|
|
28704
|
+
"America/St_Johns",
|
|
28705
|
+
"America/St_Kitts",
|
|
28706
|
+
"America/St_Lucia",
|
|
28707
|
+
"America/St_Thomas",
|
|
28708
|
+
"America/St_Vincent",
|
|
28709
|
+
"America/Swift_Current",
|
|
28710
|
+
"America/Tegucigalpa",
|
|
28711
|
+
"America/Thule",
|
|
28712
|
+
"America/Tijuana",
|
|
28713
|
+
"America/Toronto",
|
|
28714
|
+
"America/Tortola",
|
|
28715
|
+
"America/Vancouver",
|
|
28716
|
+
"America/Whitehorse",
|
|
28717
|
+
"America/Winnipeg",
|
|
28718
|
+
"America/Yakutat",
|
|
28719
|
+
"Antarctica/Casey",
|
|
28720
|
+
"Antarctica/Davis",
|
|
28721
|
+
"Antarctica/DumontDUrville",
|
|
28722
|
+
"Antarctica/Macquarie",
|
|
28723
|
+
"Antarctica/Mawson",
|
|
28724
|
+
"Antarctica/McMurdo",
|
|
28725
|
+
"Antarctica/Palmer",
|
|
28726
|
+
"Antarctica/Rothera",
|
|
28727
|
+
"Antarctica/Syowa",
|
|
28728
|
+
"Antarctica/Troll",
|
|
28729
|
+
"Antarctica/Vostok",
|
|
28730
|
+
"Arctic/Longyearbyen",
|
|
28731
|
+
"Asia/Aden",
|
|
28732
|
+
"Asia/Almaty",
|
|
28733
|
+
"Asia/Amman",
|
|
28734
|
+
"Asia/Anadyr",
|
|
28735
|
+
"Asia/Aqtau",
|
|
28736
|
+
"Asia/Aqtobe",
|
|
28737
|
+
"Asia/Ashgabat",
|
|
28738
|
+
"Asia/Atyrau",
|
|
28739
|
+
"Asia/Baghdad",
|
|
28740
|
+
"Asia/Bahrain",
|
|
28741
|
+
"Asia/Baku",
|
|
28742
|
+
"Asia/Bangkok",
|
|
28743
|
+
"Asia/Barnaul",
|
|
28744
|
+
"Asia/Beirut",
|
|
28745
|
+
"Asia/Bishkek",
|
|
28746
|
+
"Asia/Brunei",
|
|
28747
|
+
"Asia/Calcutta",
|
|
28748
|
+
"Asia/Chita",
|
|
28749
|
+
"Asia/Colombo",
|
|
28750
|
+
"Asia/Damascus",
|
|
28751
|
+
"Asia/Dhaka",
|
|
28752
|
+
"Asia/Dili",
|
|
28753
|
+
"Asia/Dubai",
|
|
28754
|
+
"Asia/Dushanbe",
|
|
28755
|
+
"Asia/Famagusta",
|
|
28756
|
+
"Asia/Gaza",
|
|
28757
|
+
"Asia/Hebron",
|
|
28758
|
+
"Asia/Hong_Kong",
|
|
28759
|
+
"Asia/Hovd",
|
|
28760
|
+
"Asia/Irkutsk",
|
|
28761
|
+
"Asia/Jakarta",
|
|
28762
|
+
"Asia/Jayapura",
|
|
28763
|
+
"Asia/Jerusalem",
|
|
28764
|
+
"Asia/Kabul",
|
|
28765
|
+
"Asia/Kamchatka",
|
|
28766
|
+
"Asia/Karachi",
|
|
28767
|
+
"Asia/Katmandu",
|
|
28768
|
+
"Asia/Khandyga",
|
|
28769
|
+
"Asia/Krasnoyarsk",
|
|
28770
|
+
"Asia/Kuala_Lumpur",
|
|
28771
|
+
"Asia/Kuching",
|
|
28772
|
+
"Asia/Kuwait",
|
|
28773
|
+
"Asia/Macau",
|
|
28774
|
+
"Asia/Magadan",
|
|
28775
|
+
"Asia/Makassar",
|
|
28776
|
+
"Asia/Manila",
|
|
28777
|
+
"Asia/Muscat",
|
|
28778
|
+
"Asia/Nicosia",
|
|
28779
|
+
"Asia/Novokuznetsk",
|
|
28780
|
+
"Asia/Novosibirsk",
|
|
28781
|
+
"Asia/Omsk",
|
|
28782
|
+
"Asia/Oral",
|
|
28783
|
+
"Asia/Phnom_Penh",
|
|
28784
|
+
"Asia/Pontianak",
|
|
28785
|
+
"Asia/Pyongyang",
|
|
28786
|
+
"Asia/Qatar",
|
|
28787
|
+
"Asia/Qostanay",
|
|
28788
|
+
"Asia/Qyzylorda",
|
|
28789
|
+
"Asia/Rangoon",
|
|
28790
|
+
"Asia/Riyadh",
|
|
28791
|
+
"Asia/Saigon",
|
|
28792
|
+
"Asia/Sakhalin",
|
|
28793
|
+
"Asia/Samarkand",
|
|
28794
|
+
"Asia/Seoul",
|
|
28795
|
+
"Asia/Shanghai",
|
|
28796
|
+
"Asia/Singapore",
|
|
28797
|
+
"Asia/Srednekolymsk",
|
|
28798
|
+
"Asia/Taipei",
|
|
28799
|
+
"Asia/Tashkent",
|
|
28800
|
+
"Asia/Tbilisi",
|
|
28801
|
+
"Asia/Tehran",
|
|
28802
|
+
"Asia/Thimphu",
|
|
28803
|
+
"Asia/Tokyo",
|
|
28804
|
+
"Asia/Tomsk",
|
|
28805
|
+
"Asia/Ulaanbaatar",
|
|
28806
|
+
"Asia/Urumqi",
|
|
28807
|
+
"Asia/Ust-Nera",
|
|
28808
|
+
"Asia/Vientiane",
|
|
28809
|
+
"Asia/Vladivostok",
|
|
28810
|
+
"Asia/Yakutsk",
|
|
28811
|
+
"Asia/Yekaterinburg",
|
|
28812
|
+
"Asia/Yerevan",
|
|
28813
|
+
"Atlantic/Azores",
|
|
28814
|
+
"Atlantic/Bermuda",
|
|
28815
|
+
"Atlantic/Canary",
|
|
28816
|
+
"Atlantic/Cape_Verde",
|
|
28817
|
+
"Atlantic/Faeroe",
|
|
28818
|
+
"Atlantic/Madeira",
|
|
28819
|
+
"Atlantic/Reykjavik",
|
|
28820
|
+
"Atlantic/South_Georgia",
|
|
28821
|
+
"Atlantic/St_Helena",
|
|
28822
|
+
"Atlantic/Stanley",
|
|
28823
|
+
"Australia/Adelaide",
|
|
28824
|
+
"Australia/Brisbane",
|
|
28825
|
+
"Australia/Broken_Hill",
|
|
28826
|
+
"Australia/Darwin",
|
|
28827
|
+
"Australia/Eucla",
|
|
28828
|
+
"Australia/Hobart",
|
|
28829
|
+
"Australia/Lindeman",
|
|
28830
|
+
"Australia/Lord_Howe",
|
|
28831
|
+
"Australia/Melbourne",
|
|
28832
|
+
"Australia/Perth",
|
|
28833
|
+
"Australia/Sydney",
|
|
28834
|
+
"Europe/Amsterdam",
|
|
28835
|
+
"Europe/Andorra",
|
|
28836
|
+
"Europe/Astrakhan",
|
|
28837
|
+
"Europe/Athens",
|
|
28838
|
+
"Europe/Belgrade",
|
|
28839
|
+
"Europe/Berlin",
|
|
28840
|
+
"Europe/Bratislava",
|
|
28841
|
+
"Europe/Brussels",
|
|
28842
|
+
"Europe/Bucharest",
|
|
28843
|
+
"Europe/Budapest",
|
|
28844
|
+
"Europe/Busingen",
|
|
28845
|
+
"Europe/Chisinau",
|
|
28846
|
+
"Europe/Copenhagen",
|
|
28847
|
+
"Europe/Dublin",
|
|
28848
|
+
"Europe/Gibraltar",
|
|
28849
|
+
"Europe/Guernsey",
|
|
28850
|
+
"Europe/Helsinki",
|
|
28851
|
+
"Europe/Isle_of_Man",
|
|
28852
|
+
"Europe/Istanbul",
|
|
28853
|
+
"Europe/Jersey",
|
|
28854
|
+
"Europe/Kaliningrad",
|
|
28855
|
+
"Europe/Kiev",
|
|
28856
|
+
"Europe/Kirov",
|
|
28857
|
+
"Europe/Lisbon",
|
|
28858
|
+
"Europe/Ljubljana",
|
|
28859
|
+
"Europe/London",
|
|
28860
|
+
"Europe/Luxembourg",
|
|
28861
|
+
"Europe/Madrid",
|
|
28862
|
+
"Europe/Malta",
|
|
28863
|
+
"Europe/Mariehamn",
|
|
28864
|
+
"Europe/Minsk",
|
|
28865
|
+
"Europe/Monaco",
|
|
28866
|
+
"Europe/Moscow",
|
|
28867
|
+
"Europe/Oslo",
|
|
28868
|
+
"Europe/Paris",
|
|
28869
|
+
"Europe/Podgorica",
|
|
28870
|
+
"Europe/Prague",
|
|
28871
|
+
"Europe/Riga",
|
|
28872
|
+
"Europe/Rome",
|
|
28873
|
+
"Europe/Samara",
|
|
28874
|
+
"Europe/San_Marino",
|
|
28875
|
+
"Europe/Sarajevo",
|
|
28876
|
+
"Europe/Saratov",
|
|
28877
|
+
"Europe/Simferopol",
|
|
28878
|
+
"Europe/Skopje",
|
|
28879
|
+
"Europe/Sofia",
|
|
28880
|
+
"Europe/Stockholm",
|
|
28881
|
+
"Europe/Tallinn",
|
|
28882
|
+
"Europe/Tirane",
|
|
28883
|
+
"Europe/Ulyanovsk",
|
|
28884
|
+
"Europe/Vaduz",
|
|
28885
|
+
"Europe/Vatican",
|
|
28886
|
+
"Europe/Vienna",
|
|
28887
|
+
"Europe/Vilnius",
|
|
28888
|
+
"Europe/Volgograd",
|
|
28889
|
+
"Europe/Warsaw",
|
|
28890
|
+
"Europe/Zagreb",
|
|
28891
|
+
"Europe/Zurich",
|
|
28892
|
+
"Indian/Antananarivo",
|
|
28893
|
+
"Indian/Chagos",
|
|
28894
|
+
"Indian/Christmas",
|
|
28895
|
+
"Indian/Cocos",
|
|
28896
|
+
"Indian/Comoro",
|
|
28897
|
+
"Indian/Kerguelen",
|
|
28898
|
+
"Indian/Mahe",
|
|
28899
|
+
"Indian/Maldives",
|
|
28900
|
+
"Indian/Mauritius",
|
|
28901
|
+
"Indian/Mayotte",
|
|
28902
|
+
"Indian/Reunion",
|
|
28903
|
+
"Pacific/Apia",
|
|
28904
|
+
"Pacific/Auckland",
|
|
28905
|
+
"Pacific/Bougainville",
|
|
28906
|
+
"Pacific/Chatham",
|
|
28907
|
+
"Pacific/Easter",
|
|
28908
|
+
"Pacific/Efate",
|
|
28909
|
+
"Pacific/Enderbury",
|
|
28910
|
+
"Pacific/Fakaofo",
|
|
28911
|
+
"Pacific/Fiji",
|
|
28912
|
+
"Pacific/Funafuti",
|
|
28913
|
+
"Pacific/Galapagos",
|
|
28914
|
+
"Pacific/Gambier",
|
|
28915
|
+
"Pacific/Guadalcanal",
|
|
28916
|
+
"Pacific/Guam",
|
|
28917
|
+
"Pacific/Honolulu",
|
|
28918
|
+
"Pacific/Kiritimati",
|
|
28919
|
+
"Pacific/Kosrae",
|
|
28920
|
+
"Pacific/Kwajalein",
|
|
28921
|
+
"Pacific/Majuro",
|
|
28922
|
+
"Pacific/Marquesas",
|
|
28923
|
+
"Pacific/Midway",
|
|
28924
|
+
"Pacific/Nauru",
|
|
28925
|
+
"Pacific/Niue",
|
|
28926
|
+
"Pacific/Norfolk",
|
|
28927
|
+
"Pacific/Noumea",
|
|
28928
|
+
"Pacific/Pago_Pago",
|
|
28929
|
+
"Pacific/Palau",
|
|
28930
|
+
"Pacific/Pitcairn",
|
|
28931
|
+
"Pacific/Ponape",
|
|
28932
|
+
"Pacific/Port_Moresby",
|
|
28933
|
+
"Pacific/Rarotonga",
|
|
28934
|
+
"Pacific/Saipan",
|
|
28935
|
+
"Pacific/Tahiti",
|
|
28936
|
+
"Pacific/Tarawa",
|
|
28937
|
+
"Pacific/Tongatapu",
|
|
28938
|
+
"Pacific/Truk",
|
|
28939
|
+
"Pacific/Wake",
|
|
28940
|
+
"Pacific/Wallis",
|
|
28941
|
+
]);
|
|
28942
|
+
function parseOffsetMinutes(rawOffset) {
|
|
28943
|
+
if (rawOffset === "GMT" || rawOffset === "UTC") {
|
|
28944
|
+
return 0;
|
|
28945
|
+
}
|
|
28946
|
+
const match = rawOffset.match(/^(?:GMT|UTC)([+-])(\d{1,2})(?::?(\d{2}))?$/);
|
|
28947
|
+
if (!match) {
|
|
28948
|
+
return 0;
|
|
28949
|
+
}
|
|
28950
|
+
const sign = match[1] === "-" ? -1 : 1;
|
|
28951
|
+
const hours = Number.parseInt(match[2] || "0", 10);
|
|
28952
|
+
const minutes = Number.parseInt(match[3] || "0", 10);
|
|
28953
|
+
return sign * (hours * 60 + minutes);
|
|
28954
|
+
}
|
|
28955
|
+
function getTimezoneOffsetMinutes(timezoneId, date = new Date()) {
|
|
28956
|
+
try {
|
|
28957
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
28958
|
+
timeZone: timezoneId,
|
|
28959
|
+
timeZoneName: "shortOffset",
|
|
28960
|
+
hour: "2-digit",
|
|
28961
|
+
minute: "2-digit",
|
|
28962
|
+
hourCycle: "h23",
|
|
28963
|
+
}).formatToParts(date);
|
|
28964
|
+
const offsetPart = parts.find((part) => part.type === "timeZoneName")?.value;
|
|
28965
|
+
return offsetPart ? parseOffsetMinutes(offsetPart) : 0;
|
|
28966
|
+
}
|
|
28967
|
+
catch {
|
|
28968
|
+
return 0;
|
|
28969
|
+
}
|
|
28970
|
+
}
|
|
28971
|
+
function formatUtcOffset(offsetMinutes) {
|
|
28972
|
+
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
28973
|
+
const absoluteMinutes = Math.abs(offsetMinutes);
|
|
28974
|
+
const hours = String(Math.floor(absoluteMinutes / 60)).padStart(2, "0");
|
|
28975
|
+
const minutes = String(absoluteMinutes % 60).padStart(2, "0");
|
|
28976
|
+
return `UTC${sign}${hours}:${minutes}`;
|
|
28977
|
+
}
|
|
28978
|
+
const IANA_TIMEZONE_OPTIONS = Object.freeze([...IANA_TIMEZONE_IDS]
|
|
28979
|
+
.map((timezoneId) => {
|
|
28980
|
+
const offsetMinutes = getTimezoneOffsetMinutes(timezoneId);
|
|
28981
|
+
return {
|
|
28982
|
+
value: timezoneId,
|
|
28983
|
+
label: `${formatUtcOffset(offsetMinutes)} • ${timezoneId}`,
|
|
28984
|
+
offsetMinutes,
|
|
28985
|
+
};
|
|
28986
|
+
})
|
|
28987
|
+
.sort((left, right) => left.offsetMinutes - right.offsetMinutes || left.value.localeCompare(right.value)));
|
|
28988
|
+
|
|
28989
|
+
const GOOGLE_IDENTITY_SCOPES = [
|
|
28990
|
+
'openid',
|
|
28991
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
|
28992
|
+
'https://www.googleapis.com/auth/userinfo.profile',
|
|
28993
|
+
];
|
|
28994
|
+
const GOOGLE_CALENDAR_SCOPE = 'https://www.googleapis.com/auth/calendar';
|
|
28995
|
+
const GOOGLE_SHEETS_SCOPE = 'https://www.googleapis.com/auth/spreadsheets';
|
|
28996
|
+
const GOOGLE_GMAIL_READ_SCOPE = 'https://www.googleapis.com/auth/gmail.readonly';
|
|
28997
|
+
const GOOGLE_GMAIL_SEND_SCOPE = 'https://www.googleapis.com/auth/gmail.send';
|
|
28998
|
+
const GOOGLE_CALENDAR_OPERATION_OPTIONS = [
|
|
28999
|
+
{
|
|
29000
|
+
value: 'google_calendar_check_availability',
|
|
29001
|
+
label: 'Check availability',
|
|
29002
|
+
description: 'Check whether a calendar is free during a time window.',
|
|
29003
|
+
},
|
|
29004
|
+
{
|
|
29005
|
+
value: 'google_calendar_list_upcoming_events',
|
|
29006
|
+
label: 'List upcoming',
|
|
29007
|
+
description: 'Read the next upcoming events from the calendar.',
|
|
29008
|
+
},
|
|
29009
|
+
{
|
|
29010
|
+
value: 'google_calendar_create_event',
|
|
29011
|
+
label: 'Create event',
|
|
29012
|
+
description: 'Create a new calendar event.',
|
|
29013
|
+
},
|
|
29014
|
+
{
|
|
29015
|
+
value: 'google_calendar_update_event',
|
|
29016
|
+
label: 'Update event',
|
|
29017
|
+
description: 'Modify an existing calendar event.',
|
|
29018
|
+
},
|
|
29019
|
+
{
|
|
29020
|
+
value: 'google_calendar_cancel_event',
|
|
29021
|
+
label: 'Cancel event',
|
|
29022
|
+
description: 'Cancel or delete an existing calendar event.',
|
|
29023
|
+
},
|
|
29024
|
+
];
|
|
29025
|
+
const GOOGLE_SHEETS_OPERATION_OPTIONS = [
|
|
29026
|
+
{
|
|
29027
|
+
value: 'google_sheets_append_row',
|
|
29028
|
+
label: 'Append row',
|
|
29029
|
+
description: 'Write a new row into a spreadsheet.',
|
|
29030
|
+
},
|
|
29031
|
+
{
|
|
29032
|
+
value: 'google_sheets_list_sheets',
|
|
29033
|
+
label: 'List sheets',
|
|
29034
|
+
description: 'List worksheet tabs and spreadsheet metadata.',
|
|
29035
|
+
},
|
|
29036
|
+
{
|
|
29037
|
+
value: 'google_sheets_read_rows',
|
|
29038
|
+
label: 'Read rows',
|
|
29039
|
+
description: 'Read rows from a worksheet range.',
|
|
29040
|
+
},
|
|
29041
|
+
];
|
|
29042
|
+
const GOOGLE_GMAIL_OPERATION_OPTIONS = [
|
|
29043
|
+
{
|
|
29044
|
+
value: 'google_gmail_search_messages',
|
|
29045
|
+
label: 'Search messages',
|
|
29046
|
+
description: 'Search Gmail and return readable message summaries.',
|
|
29047
|
+
},
|
|
29048
|
+
{
|
|
29049
|
+
value: 'google_gmail_get_message',
|
|
29050
|
+
label: 'Get message',
|
|
29051
|
+
description: 'Fetch a specific Gmail message by ID.',
|
|
29052
|
+
},
|
|
29053
|
+
{
|
|
29054
|
+
value: 'google_gmail_send_email',
|
|
29055
|
+
label: 'Send email',
|
|
29056
|
+
description: 'Send an email from the connected Gmail account.',
|
|
29057
|
+
},
|
|
29058
|
+
];
|
|
29059
|
+
const GOOGLE_MANAGED_OPERATION_OPTIONS = {
|
|
29060
|
+
google_calendar: GOOGLE_CALENDAR_OPERATION_OPTIONS,
|
|
29061
|
+
google_sheets: GOOGLE_SHEETS_OPERATION_OPTIONS,
|
|
29062
|
+
google_gmail: GOOGLE_GMAIL_OPERATION_OPTIONS,
|
|
29063
|
+
};
|
|
29064
|
+
const GOOGLE_GMAIL_REQUIRED_SCOPES_BY_OPERATION = {
|
|
29065
|
+
google_gmail_search_messages: [GOOGLE_GMAIL_READ_SCOPE],
|
|
29066
|
+
google_gmail_get_message: [GOOGLE_GMAIL_READ_SCOPE],
|
|
29067
|
+
google_gmail_send_email: [GOOGLE_GMAIL_SEND_SCOPE],
|
|
29068
|
+
};
|
|
29069
|
+
const GOOGLE_CALENDAR_REQUIRED_SCOPES_BY_OPERATION = {
|
|
29070
|
+
google_calendar_check_availability: [GOOGLE_CALENDAR_SCOPE],
|
|
29071
|
+
google_calendar_list_upcoming_events: [GOOGLE_CALENDAR_SCOPE],
|
|
29072
|
+
google_calendar_create_event: [GOOGLE_CALENDAR_SCOPE],
|
|
29073
|
+
google_calendar_update_event: [GOOGLE_CALENDAR_SCOPE],
|
|
29074
|
+
google_calendar_cancel_event: [GOOGLE_CALENDAR_SCOPE],
|
|
29075
|
+
};
|
|
29076
|
+
const GOOGLE_SHEETS_REQUIRED_SCOPES_BY_OPERATION = {
|
|
29077
|
+
google_sheets_append_row: [GOOGLE_SHEETS_SCOPE],
|
|
29078
|
+
google_sheets_list_sheets: [GOOGLE_SHEETS_SCOPE],
|
|
29079
|
+
google_sheets_read_rows: [GOOGLE_SHEETS_SCOPE],
|
|
29080
|
+
};
|
|
29081
|
+
function uniqueStrings(values) {
|
|
29082
|
+
const orderedValues = [];
|
|
29083
|
+
const seen = new Set();
|
|
29084
|
+
for (const value of values) {
|
|
29085
|
+
if (typeof value !== 'string' || !value.trim() || seen.has(value)) {
|
|
29086
|
+
continue;
|
|
29087
|
+
}
|
|
29088
|
+
seen.add(value);
|
|
29089
|
+
orderedValues.push(value);
|
|
29090
|
+
}
|
|
29091
|
+
return orderedValues;
|
|
29092
|
+
}
|
|
29093
|
+
function getManagedToolSelectedOperations(selectedOperations, options) {
|
|
29094
|
+
const orderedValues = options.map((option) => option.value);
|
|
29095
|
+
if (!Array.isArray(selectedOperations)) {
|
|
29096
|
+
return orderedValues;
|
|
29097
|
+
}
|
|
29098
|
+
const allowed = new Set(orderedValues);
|
|
29099
|
+
const selected = new Set();
|
|
29100
|
+
for (const operation of selectedOperations) {
|
|
29101
|
+
if (typeof operation === 'string' && allowed.has(operation)) {
|
|
29102
|
+
selected.add(operation);
|
|
29103
|
+
}
|
|
29104
|
+
}
|
|
29105
|
+
return orderedValues.filter((operation) => selected.has(operation));
|
|
29106
|
+
}
|
|
29107
|
+
function toggleManagedToolOperation(selectedOperations, options, operation, checked) {
|
|
29108
|
+
const nextSelected = new Set(getManagedToolSelectedOperations(selectedOperations, options));
|
|
29109
|
+
if (checked) {
|
|
29110
|
+
nextSelected.add(operation);
|
|
29111
|
+
}
|
|
29112
|
+
else {
|
|
29113
|
+
nextSelected.delete(operation);
|
|
29114
|
+
}
|
|
29115
|
+
return options
|
|
29116
|
+
.map((option) => option.value)
|
|
29117
|
+
.filter((value) => nextSelected.has(value));
|
|
29118
|
+
}
|
|
29119
|
+
function getRequiredGoogleScopes(managedTools) {
|
|
29120
|
+
const requiredScopes = [...GOOGLE_IDENTITY_SCOPES];
|
|
29121
|
+
if (managedTools?.google_calendar?.enabled) {
|
|
29122
|
+
for (const operation of getManagedToolSelectedOperations(managedTools.google_calendar.selected_operations, GOOGLE_CALENDAR_OPERATION_OPTIONS)) {
|
|
29123
|
+
requiredScopes.push(...(GOOGLE_CALENDAR_REQUIRED_SCOPES_BY_OPERATION[operation] || []));
|
|
29124
|
+
}
|
|
29125
|
+
}
|
|
29126
|
+
if (managedTools?.google_sheets?.enabled) {
|
|
29127
|
+
for (const operation of getManagedToolSelectedOperations(managedTools.google_sheets.selected_operations, GOOGLE_SHEETS_OPERATION_OPTIONS)) {
|
|
29128
|
+
requiredScopes.push(...(GOOGLE_SHEETS_REQUIRED_SCOPES_BY_OPERATION[operation] || []));
|
|
29129
|
+
}
|
|
29130
|
+
}
|
|
29131
|
+
if (managedTools?.google_gmail?.enabled) {
|
|
29132
|
+
for (const operation of getManagedToolSelectedOperations(managedTools.google_gmail.selected_operations, GOOGLE_GMAIL_OPERATION_OPTIONS)) {
|
|
29133
|
+
requiredScopes.push(...(GOOGLE_GMAIL_REQUIRED_SCOPES_BY_OPERATION[operation] || []));
|
|
29134
|
+
}
|
|
29135
|
+
}
|
|
29136
|
+
return uniqueStrings(requiredScopes);
|
|
29137
|
+
}
|
|
29138
|
+
function getMissingGoogleScopes(requiredScopes, grantedScopes) {
|
|
29139
|
+
const grantedScopeSet = new Set(uniqueStrings(grantedScopes || []));
|
|
29140
|
+
return uniqueStrings(requiredScopes || []).filter((scope) => !grantedScopeSet.has(scope));
|
|
29141
|
+
}
|
|
29142
|
+
function getMissingGoogleScopesForManagedTools(managedTools, grantedScopes) {
|
|
29143
|
+
return getMissingGoogleScopes(getRequiredGoogleScopes(managedTools), grantedScopes);
|
|
29144
|
+
}
|
|
29145
|
+
function isGoogleReconnectRequired(managedTools, grantedScopes, connected) {
|
|
29146
|
+
return connected && getMissingGoogleScopesForManagedTools(managedTools, grantedScopes).length > 0;
|
|
29147
|
+
}
|
|
29148
|
+
function getGoogleReconnectState(managedTools, status) {
|
|
29149
|
+
const required_scopes = getRequiredGoogleScopes(managedTools);
|
|
29150
|
+
const granted_scopes = status?.granted_scopes || [];
|
|
29151
|
+
const missing_scopes = getMissingGoogleScopes(required_scopes, granted_scopes);
|
|
29152
|
+
return {
|
|
29153
|
+
required_scopes,
|
|
29154
|
+
missing_scopes,
|
|
29155
|
+
reconnect_required: (Boolean(status?.connected) && missing_scopes.length > 0) ||
|
|
29156
|
+
Boolean(status?.reconnect_required),
|
|
29157
|
+
};
|
|
29158
|
+
}
|
|
29159
|
+
function hasEnabledGoogleManagedTools(managedTools) {
|
|
29160
|
+
return Boolean(managedTools?.google_calendar?.enabled ||
|
|
29161
|
+
managedTools?.google_sheets?.enabled ||
|
|
29162
|
+
managedTools?.google_gmail?.enabled);
|
|
29163
|
+
}
|
|
29164
|
+
|
|
28461
29165
|
/**
|
|
28462
29166
|
* VoiceAgentWidget - UI widget for Voice.ai
|
|
28463
29167
|
*
|
|
@@ -28920,33 +29624,39 @@ class VoiceAI {
|
|
|
28920
29624
|
/** Agent management - create, update, deploy, pause, delete agents. */
|
|
28921
29625
|
get agents() {
|
|
28922
29626
|
if (!this._agents)
|
|
28923
|
-
throw new VoiceAIError('API key required for agents API
|
|
29627
|
+
throw new VoiceAIError('API key required for agents API, or pass authToken/getAuthToken in the constructor.');
|
|
28924
29628
|
return this._agents;
|
|
28925
29629
|
}
|
|
28926
29630
|
/** Analytics - call history, transcripts, stats. */
|
|
28927
29631
|
get analytics() {
|
|
28928
29632
|
if (!this._analytics)
|
|
28929
|
-
throw new VoiceAIError('API key required for analytics API
|
|
29633
|
+
throw new VoiceAIError('API key required for analytics API, or pass authToken/getAuthToken in the constructor.');
|
|
28930
29634
|
return this._analytics;
|
|
28931
29635
|
}
|
|
28932
29636
|
/** Knowledge Base - manage RAG documents. */
|
|
28933
29637
|
get knowledgeBase() {
|
|
28934
29638
|
if (!this._knowledgeBase)
|
|
28935
|
-
throw new VoiceAIError('API key required for knowledgeBase API
|
|
29639
|
+
throw new VoiceAIError('API key required for knowledgeBase API, or pass authToken/getAuthToken in the constructor.');
|
|
28936
29640
|
return this._knowledgeBase;
|
|
28937
29641
|
}
|
|
28938
29642
|
/** Phone Numbers - search, select, release phone numbers. */
|
|
28939
29643
|
get phoneNumbers() {
|
|
28940
29644
|
if (!this._phoneNumbers)
|
|
28941
|
-
throw new VoiceAIError('API key required for phoneNumbers API
|
|
29645
|
+
throw new VoiceAIError('API key required for phoneNumbers API, or pass authToken/getAuthToken in the constructor.');
|
|
28942
29646
|
return this._phoneNumbers;
|
|
28943
29647
|
}
|
|
28944
29648
|
/** Text-to-Speech - generate speech, manage voices, clone voices. */
|
|
28945
29649
|
get tts() {
|
|
28946
29650
|
if (!this._tts)
|
|
28947
|
-
throw new VoiceAIError('API key required for tts API
|
|
29651
|
+
throw new VoiceAIError('API key required for tts API, or pass authToken/getAuthToken in the constructor.');
|
|
28948
29652
|
return this._tts;
|
|
28949
29653
|
}
|
|
29654
|
+
/** Managed tools - provider-specific OAuth/status/disconnect helpers. */
|
|
29655
|
+
get managedTools() {
|
|
29656
|
+
if (!this._managedTools)
|
|
29657
|
+
throw new VoiceAIError('API key required for managedTools API, or pass authToken/getAuthToken in the constructor.');
|
|
29658
|
+
return this._managedTools;
|
|
29659
|
+
}
|
|
28950
29660
|
/**
|
|
28951
29661
|
* Create a new VoiceAI client
|
|
28952
29662
|
*
|
|
@@ -28972,15 +29682,23 @@ class VoiceAI {
|
|
|
28972
29682
|
this.agentParticipantId = null;
|
|
28973
29683
|
this.audioLevelInterval = null;
|
|
28974
29684
|
this.apiKey = config.apiKey || '';
|
|
29685
|
+
this.authToken = config.authToken;
|
|
29686
|
+
this.getAuthToken = config.getAuthToken;
|
|
28975
29687
|
this.apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
28976
|
-
// Initialize API clients when
|
|
28977
|
-
if (this.apiKey) {
|
|
28978
|
-
const clientConfig = {
|
|
29688
|
+
// Initialize API clients when auth is provided
|
|
29689
|
+
if (this.apiKey || this.authToken || this.getAuthToken) {
|
|
29690
|
+
const clientConfig = {
|
|
29691
|
+
apiKey: this.apiKey,
|
|
29692
|
+
authToken: this.authToken,
|
|
29693
|
+
getAuthToken: this.getAuthToken,
|
|
29694
|
+
apiUrl: this.apiUrl,
|
|
29695
|
+
};
|
|
28979
29696
|
this._agents = new AgentClient(clientConfig);
|
|
28980
29697
|
this._analytics = new AnalyticsClient(clientConfig);
|
|
28981
29698
|
this._knowledgeBase = new KnowledgeBaseClient(clientConfig);
|
|
28982
29699
|
this._phoneNumbers = new PhoneNumberClient(clientConfig);
|
|
28983
29700
|
this._tts = new TTSClient(clientConfig);
|
|
29701
|
+
this._managedTools = new ManagedToolsClient(clientConfig);
|
|
28984
29702
|
}
|
|
28985
29703
|
}
|
|
28986
29704
|
// ==========================================================================
|
|
@@ -29326,11 +30044,11 @@ class VoiceAI {
|
|
|
29326
30044
|
if (this.cachedConnectionDetails && !this.isTokenExpired(this.cachedConnectionDetails.participantToken)) {
|
|
29327
30045
|
return this.cachedConnectionDetails;
|
|
29328
30046
|
}
|
|
29329
|
-
// Mode 2: Direct API call with API key (constructor or per-call)
|
|
29330
|
-
if (!this.
|
|
30047
|
+
// Mode 2: Direct API call with API key or bearer auth (constructor or per-call)
|
|
30048
|
+
if (!(await this.resolveAuthToken(options))) {
|
|
29331
30049
|
throw new Error('No authentication method configured. Use one of:\n' +
|
|
29332
30050
|
'1. connectRoom() with pre-fetched details from your backend\n' +
|
|
29333
|
-
'2. API key: new VoiceAI({ apiKey: "vk_..." })
|
|
30051
|
+
'2. API key or auth token: new VoiceAI({ apiKey: "vk_..." }) / new VoiceAI({ authToken: "..." })');
|
|
29334
30052
|
}
|
|
29335
30053
|
const connectionDetails = await this.fetchConnectionDetails(options);
|
|
29336
30054
|
this.cachedConnectionDetails = connectionDetails;
|
|
@@ -29345,11 +30063,28 @@ class VoiceAI {
|
|
|
29345
30063
|
* Used by the public getConnectionDetails() method.
|
|
29346
30064
|
*/
|
|
29347
30065
|
async fetchConnectionDetails(options) {
|
|
29348
|
-
if (!this.
|
|
29349
|
-
throw new Error('API key is required for getConnectionDetails()
|
|
30066
|
+
if (!(await this.resolveAuthToken(options))) {
|
|
30067
|
+
throw new Error('API key is required for getConnectionDetails(), or pass authToken/getAuthToken to the constructor.');
|
|
29350
30068
|
}
|
|
29351
30069
|
return this.fetchConnectionDetailsFromApi(options);
|
|
29352
30070
|
}
|
|
30071
|
+
async resolveAuthToken(options = {}) {
|
|
30072
|
+
if (options.apiKey)
|
|
30073
|
+
return options.apiKey;
|
|
30074
|
+
if (options.authToken)
|
|
30075
|
+
return options.authToken;
|
|
30076
|
+
if (this.apiKey)
|
|
30077
|
+
return this.apiKey;
|
|
30078
|
+
if (this.authToken)
|
|
30079
|
+
return this.authToken;
|
|
30080
|
+
if (this.getAuthToken) {
|
|
30081
|
+
const resolvedToken = await this.getAuthToken();
|
|
30082
|
+
if (typeof resolvedToken === 'string' && resolvedToken.trim()) {
|
|
30083
|
+
return resolvedToken;
|
|
30084
|
+
}
|
|
30085
|
+
}
|
|
30086
|
+
return '';
|
|
30087
|
+
}
|
|
29353
30088
|
async fetchConnectionDetailsFromApi(options) {
|
|
29354
30089
|
const url = options.apiUrl || this.apiUrl;
|
|
29355
30090
|
// Use test-connection-details for testMode (allows testing paused/undeployed agents)
|
|
@@ -29366,13 +30101,13 @@ class VoiceAI {
|
|
|
29366
30101
|
if (options.dynamicVariables) {
|
|
29367
30102
|
requestData.dynamic_variables = options.dynamicVariables;
|
|
29368
30103
|
}
|
|
29369
|
-
const
|
|
29370
|
-
this.effectiveApiKey =
|
|
30104
|
+
const authToken = await this.resolveAuthToken(options);
|
|
30105
|
+
this.effectiveApiKey = authToken;
|
|
29371
30106
|
const response = await fetch(endpoint, {
|
|
29372
30107
|
method: 'POST',
|
|
29373
30108
|
headers: {
|
|
29374
30109
|
'Content-Type': 'application/json',
|
|
29375
|
-
'Authorization': `Bearer ${
|
|
30110
|
+
'Authorization': `Bearer ${authToken}`
|
|
29376
30111
|
},
|
|
29377
30112
|
body: JSON.stringify(requestData)
|
|
29378
30113
|
});
|
|
@@ -29646,5 +30381,5 @@ function generateOptimalAudioOptions(options) {
|
|
|
29646
30381
|
return { ...optimalOptions, ...options };
|
|
29647
30382
|
}
|
|
29648
30383
|
|
|
29649
|
-
export { VoiceAI, VoiceAIError, VoiceAgentWidget, VoiceAI as default, generateOptimalAudioOptions };
|
|
30384
|
+
export { GOOGLE_CALENDAR_OPERATION_OPTIONS, GOOGLE_CALENDAR_SCOPE, GOOGLE_GMAIL_OPERATION_OPTIONS, GOOGLE_GMAIL_READ_SCOPE, GOOGLE_GMAIL_SEND_SCOPE, GOOGLE_IDENTITY_SCOPES, GOOGLE_MANAGED_OPERATION_OPTIONS, GOOGLE_SHEETS_OPERATION_OPTIONS, GOOGLE_SHEETS_SCOPE, IANA_TIMEZONE_OPTIONS, VoiceAI, VoiceAIError, VoiceAgentWidget, VoiceAI as default, generateOptimalAudioOptions, getGoogleReconnectState, getManagedToolSelectedOperations, getMissingGoogleScopes, getMissingGoogleScopesForManagedTools, getRequiredGoogleScopes, hasEnabledGoogleManagedTools, isGoogleReconnectRequired, toggleManagedToolOperation };
|
|
29650
30385
|
//# sourceMappingURL=index.esm.js.map
|