# `url` Tiny URL composition helper for the ElevenLabs transport. One function: `buildUrl(baseUrl, path, query?)`. ## Purpose The platform exposes around fifty REST endpoints, all rooted at the same base URL, all reached by joining a slash-prefixed path and (sometimes) a query string. Doing that with template literals at every call site inevitably accumulates subtle bugs — double slashes, missing leading slashes, `undefined` values serialised as the literal string `"undefined"`. `buildUrl` normalises the construction so adapters never have to think about it. ## Features - Strips a trailing slash from the base URL, preserves a leading slash on the path, and inserts one if missing. - Accepts `string | number | boolean | undefined` query values and silently drops `undefined` entries before serialisation. - Builds the query string with `URLSearchParams` so values are percent-encoded according to the WHATWG URL spec. - Pure and synchronous — no I/O, no allocations beyond the returned string. ## Usage: Basic Example ```ts import { buildUrl } from "./url.js"; buildUrl("https://api.elevenlabs.io", "/v1/voices"); // → "https://api.elevenlabs.io/v1/voices" buildUrl("https://api.elevenlabs.io/", "v1/voices/abc"); // → "https://api.elevenlabs.io/v1/voices/abc" ``` ## Usage: Advanced Example ```ts import { buildUrl } from "./url.js"; const url = buildUrl( "https://api.elevenlabs.io", "/v1/text-to-speech/voice-123/stream", { output_format: "mp3_44100_128", optimize_streaming_latency: 2, enable_logging: false, next_text: undefined, // dropped } ); // → "https://api.elevenlabs.io/v1/text-to-speech/voice-123/stream?output_format=mp3_44100_128&optimize_streaming_latency=2&enable_logging=false" ``` ## API Reference - `buildUrl(baseUrl: string, path: string, query?: Readonly>): string` - `baseUrl` — typically `https://api.elevenlabs.io`; trailing slash is normalised away. - `path` — leading slash is preserved or added. - `query` — optional record. `undefined` values are dropped; non-string values are stringified via `String(value)`. ## Implementation Notes - The function returns the input as-is if `query` is omitted — no `URLSearchParams` allocation when there are no parameters. - All parameters become string-typed entries on the wire because that's what `URLSearchParams.append` does, regardless of the input type. - `buildUrl` is also reused by `ElevenLabsClient.openSocket` to build WSS URLs after rewriting the scheme — the path / query semantics are the same.