Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: import.meta.resolve() #15074

Merged
merged 24 commits into from
Jul 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f26cf91
feat: import.meta.resolve()
bartlomieju Jul 4, 2022
a22db34
reset CI
bartlomieju Jul 4, 2022
1850382
update TS definitions, add test
bartlomieju Jul 4, 2022
8d66152
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 4, 2022
eca534f
lint & fix test
bartlomieju Jul 4, 2022
01addd0
add tests for import maps
bartlomieju Jul 5, 2022
c9b4e4b
revert 2nd argument
bartlomieju Jul 11, 2022
c771b78
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 13, 2022
57a0a5b
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 13, 2022
20a2bda
feat(fmt): do not add a newline between a template and its tag (#15195)
dsherret Jul 13, 2022
4dcad0c
feat(lsp): provide import map remapping diags and fixes (#15165)
kitsonk Jul 14, 2022
33e64d7
fix tests
bartlomieju Jul 14, 2022
fd4cd99
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 14, 2022
b4a398e
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 17, 2022
3f9ff74
reset CI
bartlomieju Jul 17, 2022
45a28ab
use own property
bartlomieju Jul 17, 2022
f887442
typo
bartlomieju Jul 18, 2022
796fe2e
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 18, 2022
7c01350
use private property
bartlomieju Jul 18, 2022
03e18d1
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 18, 2022
6eb9c3c
add test for broken URL
bartlomieju Jul 18, 2022
d9c5bc0
don't use TryCatch
bartlomieju Jul 18, 2022
75d9519
lint
bartlomieju Jul 18, 2022
ace01a3
Merge branch 'main' into import_meta_resolve
bartlomieju Jul 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions cli/dts/lib.deno.ns.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ declare interface ImportMeta {
* ```
*/
main: boolean;

/** A function that returns resolved specifier as if it would be imported
* using `import(specifier)`.
*
* ```ts
* console.log(import.meta.resolve("./foo.js"));
* // file:///dev/foo.js
* ```
*/
resolve(specifier: string): string;
}

/** Deno supports user timing Level 3 (see: https://w3c.github.io/user-timing)
Expand Down
2 changes: 1 addition & 1 deletion cli/tests/integration/run_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ itest!(if_main {
});

itest!(import_meta {
args: "run --quiet --reload import_meta.ts",
args: "run --quiet --reload --import-map=import_meta.importmap.json import_meta.ts",
output: "import_meta.ts.out",
});

Expand Down
11 changes: 11 additions & 0 deletions cli/tests/testdata/import_meta.importmap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"imports": {
"bare": "https://example.com/",
"https://example.com/rewrite": "https://example.com/rewritten",

"1": "https://example.com/PASS-1",
"null": "https://example.com/PASS-null",
"undefined": "https://example.com/PASS-undefined",
"[object Object]": "https://example.com/PASS-object"
}
}
31 changes: 31 additions & 0 deletions cli/tests/testdata/import_meta.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
import { assertThrows } from "../../../test_util/std/testing/asserts.ts";

console.log("import_meta", import.meta.url, import.meta.main);

import "./import_meta2.ts";

console.log("Resolving ./foo.js", import.meta.resolve("./foo.js"));
console.log("Resolving bare from import map", import.meta.resolve("bare"));
console.log(
"Resolving https://example.com/rewrite from import map",
import.meta.resolve("https://example.com/rewrite"),
);
console.log(
"Resolving without a value from import map",
import.meta.resolve(),
);
console.log(
"Resolving 1 from import map",
import.meta.resolve(1),
);
console.log(
"Resolving null from import map",
import.meta.resolve(null),
);
console.log(
"Resolving object from import map",
import.meta.resolve({}),
);
bartlomieju marked this conversation as resolved.
Show resolved Hide resolved
assertThrows(() => {
import.meta.resolve("too", "many", "arguments");
}, TypeError);
assertThrows(() => {
import.meta.resolve("://malformed/url?asdf");
}, TypeError);
7 changes: 7 additions & 0 deletions cli/tests/testdata/import_meta.ts.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
import_meta2 [WILDCARD]import_meta2.ts false
import_meta [WILDCARD]import_meta.ts true
Resolving ./foo.js file:///[WILDCARD]/foo.js
Resolving bare from import map https://example.com/
Resolving https://example.com/rewrite from import map https://example.com/rewritten
Resolving without a value from import map https://example.com/PASS-undefined
Resolving 1 from import map https://example.com/PASS-1
Resolving null from import map https://example.com/PASS-null
Resolving object from import map https://example.com/PASS-object
41 changes: 41 additions & 0 deletions core/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,47 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
let main_key = v8::String::new(scope, "main").unwrap();
let main_val = v8::Boolean::new(scope, info.main);
meta.create_data_property(scope, main_key.into(), main_val.into());

let builder =
v8::FunctionBuilder::new(import_meta_resolve).data(url_val.into());
let val = v8::FunctionBuilder::<v8::Function>::build(builder, scope).unwrap();
let resolve_key = v8::String::new(scope, "resolve").unwrap();
meta.set(scope, resolve_key.into(), val.into());
}

fn import_meta_resolve(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
if args.length() > 1 {
return throw_type_error(scope, "Invalid arguments");
}

let maybe_arg_str = args.get(0).to_string(scope);
if maybe_arg_str.is_none() {
return throw_type_error(scope, "Invalid arguments");
}
let specifier = maybe_arg_str.unwrap();
let referrer = {
let url_prop = args.data().unwrap();
url_prop.to_rust_string_lossy(scope)
};
let module_map_rc = JsRuntime::module_map(scope);
let loader = {
let module_map = module_map_rc.borrow();
module_map.loader.clone()
};
match loader.resolve(&specifier.to_rust_string_lossy(scope), &referrer, false)
{
Ok(resolved) => {
let resolved_val = serde_v8::to_v8(scope, resolved.as_str()).unwrap();
rv.set(resolved_val);
}
Err(err) => {
throw_type_error(scope, &err.to_string());
}
};
}

pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
Expand Down