/** * THE one owner of prefix-joining (spec 2026-08-06 §B1). * * A deployment's public URL carries its WHOLE path — `https://site.com/maple` — * and every URL Vendo builds attaches that prefix exactly ONCE. Every other join * idiom in this repo was a bare concat, which is how #866 (login redirect drops * the base path), #867 (returnTo double-prefix) and #914 (host-tool * double-prefix) all produced `/maple/maple/…` or `/…` with the prefix missing. * There is one implementation, here, and the callers import it. */ /** The public spelling of a path: prefixed exactly once. A path that already * carries the prefix (a prefix-preserving mount) is left alone. */ export declare function withPathPrefix(prefix: string, path: string): string; /** The local spelling of a path: the public prefix taken back off. A path * outside the prefix is left alone. */ export declare function stripPathPrefix(prefix: string, path: string): string; export declare function publicBase(baseUrl: string | URL): { origin: string; path: string; }; /** * THE join. `base` keeps its whole path; `pathOrUrl` is appended exactly once — * a `pathOrUrl` that already carries the base's prefix is left alone. An * absolute `pathOrUrl` (any scheme) passes through untouched, so a login page on * another domain rides the same rule. * * A base's userinfo rides through untouched: this is a pure joiner, and a * basic-auth host API base (`VENDO_HOST_API_URL`) is legitimate server-side. The * no-credentials rule belongs to `publicBase`, which parses PUBLIC URLs. */ export declare function joinUrl(base: string | URL, pathOrUrl: string): URL; /** * The same join for a base that may be a bare PATH — the browser client's * `baseUrl` default is `/api/vendo`, and a same-origin fetch must stay * same-origin. Returns the spelling it was given: a path stays a path, an * absolute base stays absolute. */ export declare function joinPath(base: string, pathOrUrl: string): string; /** * The ONE first-contact error when the client and the server disagree about * where the wire is mounted. Both sides are named, and the fix is the last * sentence — a mount mismatch reads as a mysterious 404 otherwise, on a surface * whose own pages render perfectly. */ export declare function mountMismatchMessage(sides: { clientBaseUrl: string; requested: string; /** Browser only: the path prefix the page itself is served under. */ pageMount?: string; }): string;