@cartesia/cartesia-js 0.0.4-alpha.0 → 1.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/.turbo/turbo-build.log +63 -45
- package/CHANGELOG.md +12 -0
- package/README.md +123 -16
- package/dist/chunk-36JBKJUN.js +119 -0
- package/dist/chunk-3F5E46FT.js +212 -0
- package/dist/{chunk-XPIMIAAE.js → chunk-3FL2SNIR.js} +1 -1
- package/dist/chunk-JGP5BIUV.js +34 -0
- package/dist/chunk-KWBSQZTY.js +25 -0
- package/dist/chunk-PQ6CIPFW.js +120 -0
- package/dist/chunk-RO7TY474.js +81 -0
- package/dist/chunk-T3RG6WV4.js +22 -0
- package/dist/{chunk-R4P7LWVZ.js → chunk-WIFMLPT5.js} +31 -6
- package/dist/chunk-WVTITUXX.js +58 -0
- package/dist/chunk-XHTDPLFR.js +19 -0
- package/dist/index.cjs +425 -166
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +13 -6
- package/dist/lib/client.cjs +49 -1
- package/dist/lib/client.d.cts +2 -0
- package/dist/lib/client.d.ts +2 -0
- package/dist/lib/client.js +3 -3
- package/dist/lib/constants.cjs +15 -8
- package/dist/lib/constants.d.cts +4 -4
- package/dist/lib/constants.d.ts +4 -4
- package/dist/lib/constants.js +6 -6
- package/dist/lib/index.cjs +310 -171
- package/dist/lib/index.d.cts +6 -2
- package/dist/lib/index.d.ts +6 -2
- package/dist/lib/index.js +9 -6
- package/dist/react/index.cjs +573 -290
- package/dist/react/index.d.cts +20 -14
- package/dist/react/index.d.ts +20 -14
- package/dist/react/index.js +157 -105
- package/dist/react/utils.js +2 -2
- package/dist/tts/index.cjs +496 -0
- package/dist/tts/index.d.cts +17 -0
- package/dist/tts/index.d.ts +17 -0
- package/dist/tts/index.js +12 -0
- package/dist/tts/player.cjs +198 -0
- package/dist/tts/player.d.cts +43 -0
- package/dist/tts/player.d.ts +43 -0
- package/dist/tts/player.js +8 -0
- package/dist/tts/source.cjs +181 -0
- package/dist/tts/source.d.cts +53 -0
- package/dist/tts/source.d.ts +53 -0
- package/dist/tts/source.js +7 -0
- package/dist/{audio → tts}/utils.cjs +25 -60
- package/dist/tts/utils.d.cts +67 -0
- package/dist/tts/utils.d.ts +67 -0
- package/dist/{audio → tts}/utils.js +2 -7
- package/dist/tts/websocket.cjs +479 -0
- package/dist/tts/websocket.d.cts +53 -0
- package/dist/tts/websocket.d.ts +53 -0
- package/dist/tts/websocket.js +11 -0
- package/dist/types/index.d.cts +50 -1
- package/dist/types/index.d.ts +50 -1
- package/dist/voices/index.cjs +157 -0
- package/dist/voices/index.d.cts +12 -0
- package/dist/voices/index.d.ts +12 -0
- package/dist/voices/index.js +9 -0
- package/package.json +2 -1
- package/src/index.ts +1 -0
- package/src/lib/client.ts +15 -1
- package/src/lib/constants.ts +15 -4
- package/src/lib/index.ts +6 -3
- package/src/react/index.ts +176 -110
- package/src/tts/index.ts +17 -0
- package/src/tts/player.ts +110 -0
- package/src/tts/source.ts +115 -0
- package/src/tts/utils.ts +150 -0
- package/src/tts/websocket.ts +214 -0
- package/src/types/index.ts +63 -0
- package/src/voices/index.ts +47 -0
- package/dist/audio/index.cjs +0 -404
- package/dist/audio/index.d.cts +0 -5
- package/dist/audio/index.d.ts +0 -5
- package/dist/audio/index.js +0 -10
- package/dist/audio/utils.d.cts +0 -5
- package/dist/audio/utils.d.ts +0 -5
- package/dist/chunk-4MHF74A7.js +0 -272
- package/dist/chunk-5TSWLYOW.js +0 -113
- package/dist/chunk-MJIFZWHS.js +0 -18
- package/dist/chunk-OVI3W3GG.js +0 -12
- package/dist/chunk-S6A27RQL.js +0 -18
- package/dist/index-C2_3XFxn.d.cts +0 -163
- package/dist/index-DgwnZezj.d.ts +0 -163
- package/src/audio/index.ts +0 -297
- package/src/audio/utils.ts +0 -220
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WebSocket
|
|
3
|
+
} from "./chunk-3F5E46FT.js";
|
|
4
|
+
import {
|
|
5
|
+
Client
|
|
6
|
+
} from "./chunk-JGP5BIUV.js";
|
|
7
|
+
|
|
8
|
+
// src/tts/index.ts
|
|
9
|
+
var TTS = class extends Client {
|
|
10
|
+
/**
|
|
11
|
+
* Get a WebSocket client for streaming audio from the TTS API.
|
|
12
|
+
*
|
|
13
|
+
* @returns {WebSocket} A Cartesia WebSocket client.
|
|
14
|
+
*/
|
|
15
|
+
websocket(options) {
|
|
16
|
+
return new WebSocket(options, {
|
|
17
|
+
apiKey: this.apiKey,
|
|
18
|
+
baseUrl: this.baseUrl
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
TTS
|
|
25
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__async,
|
|
3
|
+
__privateAdd,
|
|
4
|
+
__privateGet,
|
|
5
|
+
__privateSet
|
|
6
|
+
} from "./chunk-WIFMLPT5.js";
|
|
7
|
+
|
|
8
|
+
// src/tts/source.ts
|
|
9
|
+
import Emittery from "emittery";
|
|
10
|
+
var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate;
|
|
11
|
+
var Source = class {
|
|
12
|
+
/**
|
|
13
|
+
* Create a new Source.
|
|
14
|
+
*
|
|
15
|
+
* @param options - Options for the Source.
|
|
16
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
17
|
+
*/
|
|
18
|
+
constructor({ sampleRate }) {
|
|
19
|
+
__privateAdd(this, _emitter, new Emittery());
|
|
20
|
+
__privateAdd(this, _buffer, void 0);
|
|
21
|
+
__privateAdd(this, _readIndex, 0);
|
|
22
|
+
__privateAdd(this, _writeIndex, 0);
|
|
23
|
+
__privateAdd(this, _closed, false);
|
|
24
|
+
__privateAdd(this, _sampleRate, void 0);
|
|
25
|
+
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
26
|
+
this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
|
|
27
|
+
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
28
|
+
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
29
|
+
__privateSet(this, _sampleRate, sampleRate);
|
|
30
|
+
__privateSet(this, _buffer, new Float32Array(1024));
|
|
31
|
+
}
|
|
32
|
+
get sampleRate() {
|
|
33
|
+
return __privateGet(this, _sampleRate);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Append audio to the buffer.
|
|
37
|
+
*
|
|
38
|
+
* @param src The audio to append.
|
|
39
|
+
*/
|
|
40
|
+
enqueue(src) {
|
|
41
|
+
return __async(this, null, function* () {
|
|
42
|
+
const requiredCapacity = __privateGet(this, _writeIndex) + src.length;
|
|
43
|
+
if (requiredCapacity > __privateGet(this, _buffer).length) {
|
|
44
|
+
let newCapacity = __privateGet(this, _buffer).length;
|
|
45
|
+
while (newCapacity < requiredCapacity) {
|
|
46
|
+
newCapacity *= 2;
|
|
47
|
+
}
|
|
48
|
+
const newBuffer = new Float32Array(newCapacity);
|
|
49
|
+
newBuffer.set(__privateGet(this, _buffer));
|
|
50
|
+
__privateSet(this, _buffer, newBuffer);
|
|
51
|
+
}
|
|
52
|
+
__privateGet(this, _buffer).set(src, __privateGet(this, _writeIndex));
|
|
53
|
+
__privateSet(this, _writeIndex, __privateGet(this, _writeIndex) + src.length);
|
|
54
|
+
yield __privateGet(this, _emitter).emit("enqueue");
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Read audio from the buffer.
|
|
59
|
+
*
|
|
60
|
+
* @param dst The buffer to read the audio into.
|
|
61
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
62
|
+
* less than the length of the provided buffer.
|
|
63
|
+
*/
|
|
64
|
+
read(dst) {
|
|
65
|
+
return __async(this, null, function* () {
|
|
66
|
+
const targetReadIndex = __privateGet(this, _readIndex) + dst.length;
|
|
67
|
+
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this, _writeIndex)) {
|
|
68
|
+
yield __privateGet(this, _emitter).emit("wait");
|
|
69
|
+
yield Promise.race([
|
|
70
|
+
__privateGet(this, _emitter).once("enqueue"),
|
|
71
|
+
__privateGet(this, _emitter).once("close")
|
|
72
|
+
]);
|
|
73
|
+
yield __privateGet(this, _emitter).emit("read");
|
|
74
|
+
}
|
|
75
|
+
const read = Math.min(dst.length, __privateGet(this, _writeIndex) - __privateGet(this, _readIndex));
|
|
76
|
+
dst.set(__privateGet(this, _buffer).subarray(__privateGet(this, _readIndex), __privateGet(this, _readIndex) + read));
|
|
77
|
+
__privateSet(this, _readIndex, __privateGet(this, _readIndex) + read);
|
|
78
|
+
return read;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get the number of samples in a given duration.
|
|
83
|
+
*
|
|
84
|
+
* @param durationSecs The duration in seconds.
|
|
85
|
+
* @returns The number of samples.
|
|
86
|
+
*/
|
|
87
|
+
durationToSampleCount(durationSecs) {
|
|
88
|
+
return Math.trunc(durationSecs * __privateGet(this, _sampleRate));
|
|
89
|
+
}
|
|
90
|
+
get buffer() {
|
|
91
|
+
return __privateGet(this, _buffer);
|
|
92
|
+
}
|
|
93
|
+
get readIndex() {
|
|
94
|
+
return __privateGet(this, _readIndex);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
98
|
+
*
|
|
99
|
+
* This will emit a "close" event.
|
|
100
|
+
*
|
|
101
|
+
* @returns A promise that resolves when the source is closed.
|
|
102
|
+
*/
|
|
103
|
+
close() {
|
|
104
|
+
return __async(this, null, function* () {
|
|
105
|
+
__privateSet(this, _closed, true);
|
|
106
|
+
yield __privateGet(this, _emitter).emit("close");
|
|
107
|
+
__privateGet(this, _emitter).clearListeners();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
_emitter = new WeakMap();
|
|
112
|
+
_buffer = new WeakMap();
|
|
113
|
+
_readIndex = new WeakMap();
|
|
114
|
+
_writeIndex = new WeakMap();
|
|
115
|
+
_closed = new WeakMap();
|
|
116
|
+
_sampleRate = new WeakMap();
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
Source
|
|
120
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/tts/utils.ts
|
|
2
|
+
import base64 from "base64-js";
|
|
3
|
+
function base64ToArray(b64) {
|
|
4
|
+
const byteArrays = filterSentinel(b64).map((b) => base64.toByteArray(b));
|
|
5
|
+
const totalLength = byteArrays.reduce(
|
|
6
|
+
(acc, arr) => acc + arr.length / Float32Array.BYTES_PER_ELEMENT,
|
|
7
|
+
0
|
|
8
|
+
);
|
|
9
|
+
const result = new Float32Array(totalLength);
|
|
10
|
+
let offset = 0;
|
|
11
|
+
for (const arr of byteArrays) {
|
|
12
|
+
const floats = new Float32Array(arr.buffer);
|
|
13
|
+
result.set(floats, offset);
|
|
14
|
+
offset += floats.length;
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
function playAudioBuffer(floats, context, startAt, sampleRate) {
|
|
19
|
+
const source = context.createBufferSource();
|
|
20
|
+
const buffer = context.createBuffer(1, floats.length, sampleRate);
|
|
21
|
+
buffer.getChannelData(0).set(floats);
|
|
22
|
+
source.buffer = buffer;
|
|
23
|
+
source.connect(context.destination);
|
|
24
|
+
source.start(startAt);
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
source.onended = () => {
|
|
27
|
+
resolve();
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function createMessageHandlerForContextId(contextId, handler) {
|
|
32
|
+
return (event) => {
|
|
33
|
+
if (typeof event.data !== "string") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const message = JSON.parse(event.data);
|
|
37
|
+
if (message.context_id !== contextId) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
let chunk;
|
|
41
|
+
if (message.done) {
|
|
42
|
+
chunk = getSentinel();
|
|
43
|
+
} else {
|
|
44
|
+
chunk = message.data;
|
|
45
|
+
}
|
|
46
|
+
handler({ chunk, message: event.data });
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function getSentinel() {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function isSentinel(x) {
|
|
53
|
+
return x === getSentinel();
|
|
54
|
+
}
|
|
55
|
+
function filterSentinel(collection) {
|
|
56
|
+
return collection.filter(
|
|
57
|
+
(x) => !isSentinel(x)
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function isComplete(chunks) {
|
|
61
|
+
return isSentinel(chunks[chunks.length - 1]);
|
|
62
|
+
}
|
|
63
|
+
function getEmitteryCallbacks(emitter) {
|
|
64
|
+
return {
|
|
65
|
+
on: emitter.on.bind(emitter),
|
|
66
|
+
off: emitter.off.bind(emitter),
|
|
67
|
+
once: emitter.once.bind(emitter),
|
|
68
|
+
events: emitter.events.bind(emitter)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
base64ToArray,
|
|
74
|
+
playAudioBuffer,
|
|
75
|
+
createMessageHandlerForContextId,
|
|
76
|
+
getSentinel,
|
|
77
|
+
isSentinel,
|
|
78
|
+
filterSentinel,
|
|
79
|
+
isComplete,
|
|
80
|
+
getEmitteryCallbacks
|
|
81
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Voices
|
|
3
|
+
} from "./chunk-WVTITUXX.js";
|
|
4
|
+
import {
|
|
5
|
+
TTS
|
|
6
|
+
} from "./chunk-KWBSQZTY.js";
|
|
7
|
+
import {
|
|
8
|
+
Client
|
|
9
|
+
} from "./chunk-JGP5BIUV.js";
|
|
10
|
+
|
|
11
|
+
// src/lib/index.ts
|
|
12
|
+
var Cartesia = class extends Client {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
super(options);
|
|
15
|
+
this.tts = new TTS(options);
|
|
16
|
+
this.voices = new Voices(options);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
Cartesia
|
|
22
|
+
};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
2
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
-
var __knownSymbol = (name, symbol) => {
|
|
6
|
-
return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
7
|
-
};
|
|
8
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
8
|
var __spreadValues = (a, b) => {
|
|
10
9
|
for (var prop in b || (b = {}))
|
|
@@ -17,6 +16,29 @@ var __spreadValues = (a, b) => {
|
|
|
17
16
|
}
|
|
18
17
|
return a;
|
|
19
18
|
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __accessCheck = (obj, member, msg) => {
|
|
21
|
+
if (!member.has(obj))
|
|
22
|
+
throw TypeError("Cannot " + msg);
|
|
23
|
+
};
|
|
24
|
+
var __privateGet = (obj, member, getter) => {
|
|
25
|
+
__accessCheck(obj, member, "read from private field");
|
|
26
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
27
|
+
};
|
|
28
|
+
var __privateAdd = (obj, member, value) => {
|
|
29
|
+
if (member.has(obj))
|
|
30
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
31
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
32
|
+
};
|
|
33
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
34
|
+
__accessCheck(obj, member, "write to private field");
|
|
35
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
36
|
+
return value;
|
|
37
|
+
};
|
|
38
|
+
var __privateMethod = (obj, member, method) => {
|
|
39
|
+
__accessCheck(obj, member, "access private method");
|
|
40
|
+
return method;
|
|
41
|
+
};
|
|
20
42
|
var __async = (__this, __arguments, generator) => {
|
|
21
43
|
return new Promise((resolve, reject) => {
|
|
22
44
|
var fulfilled = (value) => {
|
|
@@ -37,10 +59,13 @@ var __async = (__this, __arguments, generator) => {
|
|
|
37
59
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
60
|
});
|
|
39
61
|
};
|
|
40
|
-
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
41
62
|
|
|
42
63
|
export {
|
|
43
64
|
__spreadValues,
|
|
44
|
-
|
|
45
|
-
|
|
65
|
+
__spreadProps,
|
|
66
|
+
__privateGet,
|
|
67
|
+
__privateAdd,
|
|
68
|
+
__privateSet,
|
|
69
|
+
__privateMethod,
|
|
70
|
+
__async
|
|
46
71
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Client
|
|
3
|
+
} from "./chunk-JGP5BIUV.js";
|
|
4
|
+
import {
|
|
5
|
+
__async
|
|
6
|
+
} from "./chunk-WIFMLPT5.js";
|
|
7
|
+
|
|
8
|
+
// src/voices/index.ts
|
|
9
|
+
var Voices = class extends Client {
|
|
10
|
+
list() {
|
|
11
|
+
return __async(this, null, function* () {
|
|
12
|
+
const response = yield this.fetch("/voices");
|
|
13
|
+
return response.json();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
get(voiceId) {
|
|
17
|
+
return __async(this, null, function* () {
|
|
18
|
+
const response = yield this.fetch(`/voices/${voiceId}`);
|
|
19
|
+
return response.json();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
create(voice) {
|
|
23
|
+
return __async(this, null, function* () {
|
|
24
|
+
const response = yield this.fetch("/voices", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: JSON.stringify(voice)
|
|
27
|
+
});
|
|
28
|
+
return response.json();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
clone(options) {
|
|
32
|
+
return __async(this, null, function* () {
|
|
33
|
+
if (options.mode === "url") {
|
|
34
|
+
const response = yield this.fetch(
|
|
35
|
+
`/voices/clone/url?link=${options.link}`,
|
|
36
|
+
{
|
|
37
|
+
method: "POST"
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
return response.json();
|
|
41
|
+
}
|
|
42
|
+
if (options.mode === "clip") {
|
|
43
|
+
const formData = new FormData();
|
|
44
|
+
formData.append("clip", options.clip);
|
|
45
|
+
const response = yield this.fetch("/voices/clone/clip", {
|
|
46
|
+
method: "POST",
|
|
47
|
+
body: formData
|
|
48
|
+
});
|
|
49
|
+
return response.json();
|
|
50
|
+
}
|
|
51
|
+
throw new Error("Invalid mode for clone()");
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
Voices
|
|
58
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/lib/constants.ts
|
|
2
|
+
var BASE_URL = "https://api.cartesia.ai/";
|
|
3
|
+
var CARTESIA_VERSION = "2024-06-10";
|
|
4
|
+
var constructApiUrl = (baseUrl, path, protocol) => {
|
|
5
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
6
|
+
if (!protocol) {
|
|
7
|
+
return new URL(`${baseUrl}${normalizedPath}`);
|
|
8
|
+
}
|
|
9
|
+
if (!["http", "ws"].includes(protocol)) {
|
|
10
|
+
throw new Error(`Invalid protocol: ${protocol}`);
|
|
11
|
+
}
|
|
12
|
+
return new URL(`${baseUrl.replace(/^http/, protocol)}${normalizedPath}`);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
BASE_URL,
|
|
17
|
+
CARTESIA_VERSION,
|
|
18
|
+
constructApiUrl
|
|
19
|
+
};
|