mirror of
https://github.com/wkulhanek/bonob.git
synced 2025-12-22 01:43:29 +01:00
Add support for running under a context path, ie. /bonob, replace BONOB_WEB_ADDRESS with BONOB_URL
This commit is contained in:
72
src/url_builder.ts
Normal file
72
src/url_builder.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
function isURL(url: string | URL): url is URL {
|
||||
return (url as URL).href !== undefined;
|
||||
}
|
||||
|
||||
function isURLSearchParams(
|
||||
searchParams: Record<string, string> | URLSearchParams
|
||||
): searchParams is URLSearchParams {
|
||||
return (searchParams as URLSearchParams).getAll !== undefined;
|
||||
}
|
||||
|
||||
const stripTrailingSlash = (url: string) =>
|
||||
url.endsWith("/") ? url.substring(0, url.length - 1) : url;
|
||||
|
||||
export class URLBuilder {
|
||||
private url: URL;
|
||||
|
||||
constructor(url: string | URL) {
|
||||
this.url = isURL(url) ? url : new URL(url);
|
||||
}
|
||||
|
||||
public append = (
|
||||
bits: Partial<{
|
||||
pathname: string | undefined;
|
||||
searchParams: Record<string, string> | URLSearchParams;
|
||||
}> = { pathname: undefined, searchParams: undefined }
|
||||
) => {
|
||||
let result = new URLBuilder(this.url);
|
||||
if (bits.pathname)
|
||||
result = result.with({
|
||||
pathname: stripTrailingSlash(this.url.pathname) + bits.pathname,
|
||||
});
|
||||
if (bits.searchParams) {
|
||||
const newSearchParams = new URLSearchParams(this.url.searchParams);
|
||||
(isURLSearchParams(bits.searchParams)
|
||||
? bits.searchParams
|
||||
: new URLSearchParams(bits.searchParams)
|
||||
).forEach((v, k) => newSearchParams.append(k, v));
|
||||
result = result.with({ searchParams: newSearchParams });
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
public with = (
|
||||
bits: Partial<{
|
||||
pathname: string | undefined;
|
||||
searchParams: Record<string, string> | URLSearchParams;
|
||||
}> = { pathname: undefined, searchParams: undefined }
|
||||
) => {
|
||||
const result = new URL(this.url.href);
|
||||
if (bits.pathname) result.pathname = bits.pathname;
|
||||
if (bits.searchParams) {
|
||||
const keysToDelete: string[] = [];
|
||||
result.searchParams.forEach((_, k) => keysToDelete.push(k));
|
||||
keysToDelete.forEach((k) => result.searchParams.delete(k));
|
||||
(isURLSearchParams(bits.searchParams)
|
||||
? bits.searchParams
|
||||
: new URLSearchParams(bits.searchParams)
|
||||
).forEach((v, k) => result.searchParams.append(k, v));
|
||||
}
|
||||
return new URLBuilder(result);
|
||||
};
|
||||
|
||||
public href = () => this.url.href;
|
||||
public pathname = () => this.url.pathname;
|
||||
public searchParams = () => this.url.searchParams;
|
||||
public path = () => this.url.pathname + this.url.search;
|
||||
public toString = () => this.url.href;
|
||||
}
|
||||
|
||||
export default function url(url: string | URL): URLBuilder {
|
||||
return new URLBuilder(url);
|
||||
}
|
||||
Reference in New Issue
Block a user