Const
adding a new uri protocol scheme named "base64-scheme"
to our registry, and then forbidding it from being used as a base url:
import { assertEquals, assertThrows } from "jsr:@std/assert"
// aliasing our functions for brevity
const eq = assertEquals, err = assertThrows
// initially, our custom "base64" scheme is unidentifiable, and cannot be used in `resolveAsUrl` as a base url
eq(getUriScheme("base64://a/b/c.txt"), "relative")
err(() => resolveAsUrl("./w.xyz", "base64://a/b/c.txt")) // "base64://a/b/c.txt" is identified as a relative path, and cannot be used as a base path
// registering the custom protocol-scheme mapping.
// note that you will have to declare `as any`, since the schemes are tightly defined by the type `UriScheme`.
uriProtocolSchemeMap.push(["base64://", "base64-scheme" as any])
// and now, our custom "base64" scheme becomes identifiable.
eq(getUriScheme("base64://a/b/c.txt"), "base64-scheme")
// it is also now accepted by `resolveAsUrl` as a base uri
eq(resolveAsUrl("./w.xyz", "base64://a/b/c.txt"), new URL("base64://a/b/w.xyz"))
// since we don't want to make it possible to have "base64-scheme" as a base uri, so we'll put it in the forbidden list.
// once again `as any` is needed, since the `UriScheme` is tightly defined, and its definition cannot be changed.
forbiddenBaseUriSchemes.push("base64-scheme" as any)
err(() => resolveAsUrl("./w.xyz", "base64://a/b/c.txt")) // "base64://a/b/c.txt" is now amongst the forbidden schemes that cannot be combined with relative paths.
eq(resolveAsUrl("base64://a/b/c.txt"), new URL("base64://a/b/c.txt")) // this is of course not stopping us from building urls with the "base64" scheme, so long as no relative path is attached.
here, you can specify which uri schemes cannot be used as a base url for resolving a url via the resolveAsUrl function.