@oazmi/kitchensink - v0.9.13
    Preparing search index...

    Function resolveAsUrl

    • convert a url string to an actual URL object. your input path url can use any scheme supported by the getUriScheme function. and you may also use paths with windows dir-separators ("\"), as this function implicitly converts them a posix separator ("/").

      if you pass a URL object, then it will be returned as is.

      Parameters

      • path: string | URL
      • Optionalbase: string | URL

      Returns URL

      Error an error will be thrown if base uri is either a relative path, or uses a data uri scheme, or if the provided path is relative, but no absolute base path is provided.

      import { assertEquals, assertThrows } from "jsr:@std/assert"

      // aliasing our functions for brevity
      const eq = assertEquals, err = assertThrows, fn = resolveAsUrl

      eq(fn(new URL("some://url:8000/a/b c.txt")), new URL("some://url:8000/a/b%20c.txt"))

      eq(fn("/a/b/c d e.txt"), new URL("file:///a/b/c%20d%20e.txt"))
      eq(fn("~/a/b/c.txt"), new URL("file://~/a/b/c.txt"))
      eq(fn("C:/a/b/c/d/e.txt"), new URL("file:///C:/a/b/c/d/e.txt"))
      eq(fn("C:\\a\\b\\c\\d\\e.txt"), new URL("file:///C:/a/b/c/d/e.txt"))
      eq(fn("./e/f g.txt", "C:/a\\b\\c d/"), new URL("file:///C:/a/b/c%20d/e/f%20g.txt"))
      eq(fn("../c d/e/f g.txt", "C:/a/b/c d/"), new URL("file:///C:/a/b/c%20d/e/f%20g.txt"))
      eq(fn("d/../.././e.txt", "C:/a/b/c/"), new URL("file:///C:/a/b/e.txt"))
      eq(fn("d/../.././e.txt", "C:/a/b/c"), new URL("file:///C:/a/e.txt"))
      eq(fn("D:/a/b.txt", "C:/c/d.txt"), new URL("file:///D:/a/b.txt"))
      eq(fn("/a/b.txt", "C:/c/d.txt"), new URL("file:///C:/a/b.txt"))
      eq(fn("/a/b.txt", "/sys/admin/"), new URL("file:///a/b.txt"))
      eq(fn("/a/b.txt", ""), new URL("file:///a/b.txt"))

      eq(fn("http://cdn.esm.sh/a/b/c.txt"), new URL("http://cdn.esm.sh/a/b/c.txt"))
      eq(fn("http://cdn.esm.sh/a.txt", "file:///b/"), new URL("http://cdn.esm.sh/a.txt"))
      eq(fn("http://cdn.esm.sh/a.txt", "/b/"), new URL("http://cdn.esm.sh/a.txt"))
      eq(fn("/a/b/c.txt", "http://cdn.esm.sh/"), new URL("http://cdn.esm.sh/a/b/c.txt"))

      eq(fn("b/c.txt", "http://cdn.esm.sh/a/"), new URL("http://cdn.esm.sh/a/b/c.txt"))
      eq(fn("b/c.txt", "http://cdn.esm.sh/a"), new URL("http://cdn.esm.sh/b/c.txt"))
      eq(fn("./b/c.txt", "http://cdn.esm.sh/a/"), new URL("http://cdn.esm.sh/a/b/c.txt"))
      eq(fn("./b/c.txt", "http://cdn.esm.sh/a"), new URL("http://cdn.esm.sh/b/c.txt"))
      eq(fn("../b/c.txt", "https://cdn.esm.sh/a/"), new URL("https://cdn.esm.sh/b/c.txt"))
      eq(fn("../c/d.txt", "https://cdn.esm.sh/a/b"), new URL("https://cdn.esm.sh/c/d.txt"))
      eq(fn("/c/d.txt", "https://cdn.esm.sh/a/b"), new URL("https://cdn.esm.sh/c/d.txt"))

      eq(fn("node:fs"), new URL("node:/fs/"))
      eq(fn("node:fs/promises"), new URL("node:/fs/promises"))
      eq(fn("promises", "node:fs"), new URL("node:/fs/promises"))
      eq(fn("./promises", "node:fs"), new URL("node:/fs/promises"))
      eq(fn("./promises", "node:fs/"), new URL("node:/fs/promises"))
      eq(fn("mkdir", "node:fs/promises"), new URL("node:/fs/mkdir"))
      eq(fn("mkdir", "node:fs/promises/"), new URL("node:/fs/promises/mkdir"))
      eq(fn("./mkdir", "node:fs/promises"), new URL("node:/fs/mkdir"))
      eq(fn("./mkdir", "node:fs/promises/"), new URL("node:/fs/promises/mkdir"))
      eq(fn("/sync", "node:fs/promises/mkdir"), new URL("node:/fs/sync"))

      eq(fn("npm:react"), new URL("npm:/react/"))
      eq(fn("npm:react/file.txt"), new URL("npm:/react/file.txt"))
      eq(fn("npm:@facebook/react"), new URL("npm:/@facebook/react/"))
      eq(fn("./to/file.txt", "npm:react"), new URL("npm:/react/to/file.txt"))
      eq(fn("./to/file.txt", "npm:react/"), new URL("npm:/react/to/file.txt"))
      eq(fn("/to/file.txt", "npm:react/native/bin"), new URL("npm:/react/to/file.txt"))
      eq(fn("npm:react@19/jsx runtime.ts"), new URL("npm:/react@19/jsx%20runtime.ts"))
      eq(fn("npm:react@^19 <19.5/jsx.ts"), new URL("npm:/react@%5E19%20%3C19.5/jsx.ts"))

      eq(fn("jsr:@scope/my-lib/b.txt"), new URL("jsr:/@scope/my-lib/b.txt"))
      eq(fn("a/b.txt", "jsr:///@scope/my-lib"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("./a/b.txt", "jsr:///@scope/my-lib"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("a/b.txt", "jsr:///@scope/my-lib/c"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("./a/b.txt", "jsr:///@scope/my-lib/c"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("./a/b.txt", "jsr:///@scope/my-lib//c"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("../a/b.txt", "jsr:/@scope/my-lib///c/"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("./a/b.txt", "jsr:///@scope/my-lib/c/"), new URL("jsr:/@scope/my-lib/c/a/b.txt"))
      eq(fn("/a/b.txt", "jsr:my-lib/x/y/"), new URL("jsr:/my-lib/a/b.txt"))
      eq(fn("/a/b.txt", "jsr:@scope/my-lib/x/y/z"), new URL("jsr:/@scope/my-lib/a/b.txt"))
      eq(fn("/a/b.txt", "jsr:my-lib@1 || 2/x/y/z"), new URL("jsr:/my-lib@1%20%7C%7C%202/a/b.txt"))
      eq(fn("/a/b.txt", "jsr:@my/lib@1||2/x/y/z"), new URL("jsr:/@my/lib@1%7C%7C2/a/b.txt"))

      eq(fn("C:/a/b.txt", "jsr:@my/lib/x/y"), new URL("file:///C:/a/b.txt"))
      eq(fn("jsr:@my/lib/x/y", "C:/a/b.txt"), new URL("jsr:/@my/lib/x/y"))
      eq(fn("http://test.io/abc", "C:/a/b.txt"), new URL("http://test.io/abc"))

      eq(fn("blob:https://example.com/480-a78"), new URL("blob:https://example.com/480-a78"))
      eq(fn("data:text/plain;utf8,hello"), new URL("data:text/plain;utf8,hello"))
      eq(fn("data:text/plain;utf8,hello", "C:/a/b/"), new URL("data:text/plain;utf8,hello"))

      err(() => fn("./a/b.txt", "data:text/plain;charset=utf-8;base64,aGVsbG8="))
      err(() => fn("./a/b.txt", "blob:https://example.com/4800d2d8-a78c-4895-b68b-3690b69a0d6a"))
      err(() => fn("./a/b.txt", "./path/")) // a base path must not be relative
      err(() => fn("./a/b.txt")) // a relative path cannot be resolved on its own without a base path
      err(() => fn("./a/b.txt", "")) // an empty base path is as good as a non-existing one
      err(() => fn("fs/promises", "node:")) // the base protocol ("node:") MUST be accompanied with a package name