aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar dave caruso <me@paperdave.net> 2023-09-19 21:00:12 -0700
committerGravatar dave caruso <me@paperdave.net> 2023-09-19 21:00:12 -0700
commita9199bcfe3635de7914dfb679e14c1f33d2b65fd (patch)
tree0f520933eb58faad896fd58d3d1a938954e7dd7b
parent94fc2a7be96e0a0c6fbed8ccb7b483b562f1de5f (diff)
downloadbun-dave/import.meta.resolve.tar.gz
bun-dave/import.meta.resolve.tar.zst
bun-dave/import.meta.resolve.zip
-rw-r--r--src/bun.js/bindings/ImportMetaObject.cpp8
-rw-r--r--test/js/bun/resolve/import-meta-resolve.test.mjs95
-rw-r--r--test/js/bun/resolve/import-meta.test.js10
3 files changed, 101 insertions, 12 deletions
diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp
index b3b1a6a94..ab61072af 100644
--- a/src/bun.js/bindings/ImportMetaObject.cpp
+++ b/src/bun.js/bindings/ImportMetaObject.cpp
@@ -349,8 +349,12 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve,
return JSC::JSValue::encode(JSC::JSValue {});
}
- // Stringified URL to a file, going off assumption that all modules would be file URLs
- RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, makeString("file://"_s, result.toWTFString(globalObject)))));
+ auto resultString = result.toWTFString(globalObject);
+ if (resultString.startsWith("/"_s)) {
+ // file path -> url
+ RELEASE_AND_RETURN(scope, JSValue::encode(jsString(vm, WTF::URL::fileURLWithFileSystemPath(resultString).string())));
+ }
+ return JSValue::encode(result);
}
enum class ImportMetaPropertyOffset : uint32_t {
diff --git a/test/js/bun/resolve/import-meta-resolve.test.mjs b/test/js/bun/resolve/import-meta-resolve.test.mjs
new file mode 100644
index 000000000..ba28488a5
--- /dev/null
+++ b/test/js/bun/resolve/import-meta-resolve.test.mjs
@@ -0,0 +1,95 @@
+// You can run this test in Node.js/Deno
+import assert from "node:assert";
+
+const { test } = process?.versions?.bun ? Bun.jest(import.meta.path) : {};
+
+function wrapped(name, f) {
+ if (test) {
+ test(name, f);
+ } else {
+ f();
+ console.log("✅", name);
+ }
+}
+
+function fileUrlRelTo(actual, expected_rel) {
+ try {
+ var compareTo;
+ wrapped(expected_rel, () => {
+ actual = actual();
+ if (actual instanceof URL) actual = actual.toString();
+
+ compareTo = new URL(expected_rel, import.meta.url).toString();
+ assert.strictEqual(actual, compareTo);
+ });
+ } catch (error) {
+ if (typeof actual == "function") {
+ console.log(" ", error.message);
+ return;
+ }
+ console.log("❌", expected_rel);
+ console.log(" want: \x1b[32m%s\x1b[0m", compareTo);
+ console.log(" got: \x1b[31m%s\x1b[0m", actual);
+ return;
+ }
+}
+
+function exact(actual, expected) {
+ try {
+ wrapped(expected, () => {
+ actual = actual();
+ if (actual instanceof URL) actual = actual.toString();
+ assert.strictEqual(actual, expected);
+ });
+ } catch (error) {
+ console.log("❌", expected);
+ if (typeof actual == "function") {
+ console.log(" ", error.message);
+ return;
+ }
+ console.log(" want: \x1b[32m%s\x1b[0m", expected);
+ console.log(" got: \x1b[31m%s\x1b[0m", actual);
+ return;
+ }
+}
+
+function throws(compute, label) {
+ if (test) {
+ }
+ try {
+ wrapped(label, () => {
+ try {
+ compute();
+ } catch (error) {
+ return;
+ }
+ throw new Error("Test failed");
+ });
+ } catch {
+ console.log("❌", label);
+ }
+}
+
+fileUrlRelTo(() => import.meta.resolve("./haha.mjs"), "./haha.mjs");
+fileUrlRelTo(() => import.meta.resolve("../haha.mjs"), "../haha.mjs");
+fileUrlRelTo(() => import.meta.resolve("/haha.mjs"), "/haha.mjs");
+fileUrlRelTo(() => import.meta.resolve("/haha"), "/haha");
+fileUrlRelTo(() => import.meta.resolve("/~"), "/~");
+fileUrlRelTo(() => import.meta.resolve("./🅱️un"), "./🅱️un");
+
+// will fail on deno because it is `npm:*` specifier not a file path
+fileUrlRelTo(() => import.meta.resolve("lodash"), "../../../node_modules/lodash/lodash.js");
+
+exact(() => import.meta.resolve("node:path"), "node:path");
+exact(() => import.meta.resolve("path"), process?.versions?.bun ? "path" : "node:path");
+exact(() => import.meta.resolve("node:doesnotexist"), "node:doesnotexist");
+
+if (process?.versions?.bun) {
+ exact(() => import.meta.resolve("bun:sqlite"), "bun:sqlite");
+ exact(() => import.meta.resolve("bun:doesnotexist"), "bun:doesnotexist");
+}
+
+fileUrlRelTo(() => import.meta.resolve("./something.node"), "./something.node");
+
+throws(() => import.meta.resolve("adsjfdasdf"), "nonexistant package");
+throws(() => import.meta.resolve(""), "empty specifier");
diff --git a/test/js/bun/resolve/import-meta.test.js b/test/js/bun/resolve/import-meta.test.js
index 0b77b74be..a940d0c87 100644
--- a/test/js/bun/resolve/import-meta.test.js
+++ b/test/js/bun/resolve/import-meta.test.js
@@ -197,13 +197,3 @@ it("import non exist error code", async () => {
expect(e.code).toBe("ERR_MODULE_NOT_FOUND");
}
});
-
-it("import.meta.resolve", () => {
- expect(import.meta.resolve("./relative-filepath.js")).toBe(
- new URL("./relative-filepath.js", import.meta.url).toString(),
- );
- expect(import.meta.resolve("../relative-filepath.js")).toBe(
- new URL("../relative-filepath.js", import.meta.url).toString(),
- );
- expect(import.meta.resolve(".../relative-filepath.js")).toBe();
-});