Skip to content

Commit

Permalink
feat(utils): add pathToFileURL
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Feb 21, 2024
1 parent 58407dd commit cdcbcb7
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,20 @@ console.log(fileURLToPath("file:///foo/bar.js"));
console.log(fileURLToPath("file:///C:/path/"));
```
### `pathToFileURL`
Similar to [url.pathToFileURL](https://nodejs.org/api/url.html#urlpathtofileurlpath) but also handles `URL` input and returns a **string** with `file://` protocol.

```js
import { pathToFileURL } from "mlly";
// /foo/bar.js
console.log(pathToFileURL("foo/bar.js"));
// C:/path
console.log(pathToFileURL("C:\\path"));
```

### `normalizeid`

Ensures id has either of `node:`, `data:`, `http:`, `https:` or `file:` protocols.
Expand Down
9 changes: 8 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { fileURLToPath as _fileURLToPath } from "node:url";
import {
fileURLToPath as _fileURLToPath,
pathToFileURL as _pathToFileURL,
} from "node:url";
import { promises as fsp } from "node:fs";
import { normalizeSlash, BUILTIN_MODULES } from "./_utils";

Expand All @@ -9,6 +12,10 @@ export function fileURLToPath(id: string | URL): string {
return normalizeSlash(_fileURLToPath(id));
}

export function pathToFileURL(id: string | URL): string {
return _pathToFileURL(fileURLToPath(id)).toString();
}

// https://datatracker.ietf.org/doc/html/rfc2396
// eslint-disable-next-line no-control-regex
const INVALID_CHAR_RE = /[\u0000-\u001F"#$&*+,/:;<=>?@[\]^`{|}\u007F]+/g;
Expand Down
3 changes: 1 addition & 2 deletions test/resolve.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { existsSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { describe, it, expect } from "vitest";
import { resolveSync, resolvePathSync } from "../src";
import { resolveSync, resolvePathSync, fileURLToPath } from "../src";

const tests = [
// Resolve to path
Expand Down
28 changes: 28 additions & 0 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
getProtocol,
parseNodeModulePath,
lookupNodeModuleSubpath,
fileURLToPath,
pathToFileURL,
} from "../src";

describe("isNodeBuiltin", () => {
Expand Down Expand Up @@ -155,3 +157,29 @@ describe("lookupNodeModuleSubpath", () => {
});
}
});

describe("fileURLToPath", () => {
const tests = [
// ["file:///C:/path/", "C:\\path\\"], // TODO
// ["file://nas/foo.txt", "\\\\nas\\foo.txt"], // TODO
["file:///你好.txt", "/你好.txt"],
["file:///hello world", "/hello world"],
] as const;
for (const t of tests) {
it(`${t[0]} should resolve to ${t[1]}`, () => {
expect(fileURLToPath(t[0])).toBe(t[1]);
});
}
});

describe("pathToFileURL", () => {
const tests = [
["/foo#1", "file:///foo%231"],
["/some/path%.c", "file:///some/path%25.c"],
] as const;
for (const t of tests) {
it(`${t[0]} should resolve to ${t[1]}`, () => {
expect(pathToFileURL(t[0])).toBe(t[1]);
});
}
});

0 comments on commit cdcbcb7

Please sign in to comment.