Skip to content

Commit cdcbcb7

Browse files
committedFeb 21, 2024
feat(utils): add pathToFileURL
1 parent 58407dd commit cdcbcb7

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed
 

‎README.md

+14
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,20 @@ console.log(fileURLToPath("file:///foo/bar.js"));
424424
console.log(fileURLToPath("file:///C:/path/"));
425425
```
426426
427+
### `pathToFileURL`
428+
429+
Similar to [url.pathToFileURL](https://nodejs.org/api/url.html#urlpathtofileurlpath) but also handles `URL` input and returns a **string** with `file://` protocol.
430+
431+
```js
432+
import { pathToFileURL } from "mlly";
433+
434+
// /foo/bar.js
435+
console.log(pathToFileURL("foo/bar.js"));
436+
437+
// C:/path
438+
console.log(pathToFileURL("C:\\path"));
439+
```
440+
427441
### `normalizeid`
428442

429443
Ensures id has either of `node:`, `data:`, `http:`, `https:` or `file:` protocols.

‎src/utils.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { fileURLToPath as _fileURLToPath } from "node:url";
1+
import {
2+
fileURLToPath as _fileURLToPath,
3+
pathToFileURL as _pathToFileURL,
4+
} from "node:url";
25
import { promises as fsp } from "node:fs";
36
import { normalizeSlash, BUILTIN_MODULES } from "./_utils";
47

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

15+
export function pathToFileURL(id: string | URL): string {
16+
return _pathToFileURL(fileURLToPath(id)).toString();
17+
}
18+
1219
// https://datatracker.ietf.org/doc/html/rfc2396
1320
// eslint-disable-next-line no-control-regex
1421
const INVALID_CHAR_RE = /[\u0000-\u001F"#$&*+,/:;<=>?@[\]^`{|}\u007F]+/g;

‎test/resolve.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { existsSync } from "node:fs";
2-
import { fileURLToPath } from "node:url";
32
import { describe, it, expect } from "vitest";
4-
import { resolveSync, resolvePathSync } from "../src";
3+
import { resolveSync, resolvePathSync, fileURLToPath } from "../src";
54

65
const tests = [
76
// Resolve to path

‎test/utils.test.ts

+28
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
getProtocol,
77
parseNodeModulePath,
88
lookupNodeModuleSubpath,
9+
fileURLToPath,
10+
pathToFileURL,
911
} from "../src";
1012

1113
describe("isNodeBuiltin", () => {
@@ -155,3 +157,29 @@ describe("lookupNodeModuleSubpath", () => {
155157
});
156158
}
157159
});
160+
161+
describe("fileURLToPath", () => {
162+
const tests = [
163+
// ["file:///C:/path/", "C:\\path\\"], // TODO
164+
// ["file://nas/foo.txt", "\\\\nas\\foo.txt"], // TODO
165+
["file:///你好.txt", "/你好.txt"],
166+
["file:///hello world", "/hello world"],
167+
] as const;
168+
for (const t of tests) {
169+
it(`${t[0]} should resolve to ${t[1]}`, () => {
170+
expect(fileURLToPath(t[0])).toBe(t[1]);
171+
});
172+
}
173+
});
174+
175+
describe("pathToFileURL", () => {
176+
const tests = [
177+
["/foo#1", "file:///foo%231"],
178+
["/some/path%.c", "file:///some/path%25.c"],
179+
] as const;
180+
for (const t of tests) {
181+
it(`${t[0]} should resolve to ${t[1]}`, () => {
182+
expect(pathToFileURL(t[0])).toBe(t[1]);
183+
});
184+
}
185+
});

0 commit comments

Comments
 (0)
Please sign in to comment.