diff --git a/deno.json b/deno.json index 3367cfa..3a39ba8 100644 --- a/deno.json +++ b/deno.json @@ -19,7 +19,7 @@ "deno", "src/rs_lib/target", "target", - "tests/jsx/testdata" + "tests/**/testdata" ], "imports": { "@david/dax": "jsr:@david/dax@^0.43.2", diff --git a/src/rs_lib/lib.rs b/src/rs_lib/lib.rs index ac78e64..05d54a6 100644 --- a/src/rs_lib/lib.rs +++ b/src/rs_lib/lib.rs @@ -16,6 +16,7 @@ use deno_cache_dir::file_fetcher::NullBlobStore; use deno_graph::MediaType; use deno_graph::Module; use deno_graph::ModuleGraph; +use deno_graph::Position; use deno_graph::analysis::ModuleAnalyzer; use deno_graph::ast::DefaultModuleAnalyzer; use deno_graph::ast::EsParser; @@ -339,10 +340,9 @@ impl DenoLoader { &mut self, roots: Vec, ) -> Result<(), anyhow::Error> { - let cwd = self.workspace_factory.initial_cwd(); let roots = roots .into_iter() - .map(|e| parse_entrypoint(e, &cwd)) + .map(|e| self.resolve_entrypoint(e)) .collect::, _>>()?; let npm_package_info_provider = self .npm_installer_factory @@ -441,9 +441,7 @@ impl DenoLoader { )?, ), None => { - let entrypoint = - parse_entrypoint(specifier, self.workspace_factory.initial_cwd())? - .to_string(); + let entrypoint = self.resolve_entrypoint(specifier)?.to_string(); ( entrypoint, deno_path_util::url_from_file_path( @@ -599,6 +597,26 @@ impl DenoLoader { Ok(Cow::Borrowed(source.as_bytes())) } } + + fn resolve_entrypoint( + &self, + specifier: String, + ) -> Result { + let cwd = self.workspace_factory.initial_cwd(); + if specifier.contains('\\') { + return Ok(deno_path_util::url_from_file_path(&resolve_absolute_path( + specifier, cwd, + ))?); + } + let referrer = deno_path_util::url_from_directory_path(cwd)?; + Ok(self.resolver.resolve( + &specifier, + &referrer, + Position::zeroed(), + node_resolver::ResolutionMode::Import, + node_resolver::NodeResolutionKind::Execution, + )?) + } } fn create_module_response( @@ -641,24 +659,6 @@ fn create_external_repsonse(url: &Url) -> JsValue { obj.into() } -fn parse_entrypoint( - entrypoint: String, - cwd: &Path, -) -> Result { - if entrypoint.starts_with("jsr:") - || entrypoint.starts_with("https:") - || entrypoint.starts_with("http:") - || entrypoint.starts_with("file:") - || entrypoint.starts_with("npm:") - { - Ok(Url::parse(&entrypoint)?) - } else { - Ok(deno_path_util::url_from_file_path(&resolve_absolute_path( - entrypoint, cwd, - ))?) - } -} - fn resolve_absolute_path(path: String, cwd: &Path) -> PathBuf { let path = sys_traits::impls::wasm_string_to_path(path); cwd.join(path) diff --git a/tests/helpers.ts b/tests/helpers.ts index 7563334..a58a575 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -21,8 +21,19 @@ export async function createLoader( }; } -export function assertResponseText(response: LoadResponse, text: string) { +export function assertResponseText( + response: LoadResponse, + text: string, + opts?: { skipSourceMap?: boolean }, +) { assertEquals(response.kind, "module"); const moduleResponse = response as ModuleLoadResponse; - assertEquals(new TextDecoder().decode(moduleResponse.code), text); + let actualText = new TextDecoder().decode(moduleResponse.code); + if (opts?.skipSourceMap) { + actualText = actualText.replace( + /\/\/# sourceMappingURL=.*$/, + "", + ); + } + assertEquals(actualText, text); } diff --git a/tests/jsx/main.test.ts b/tests/jsx/main.test.ts index 1d7393b..4066ee0 100644 --- a/tests/jsx/main.test.ts +++ b/tests/jsx/main.test.ts @@ -1,9 +1,9 @@ -import { assert } from "node:console"; import { assertResponseText, createLoader, ResolutionMode, } from "../helpers.ts"; +import { assert } from "@std/assert"; Deno.test("loads jsx transpiled", async () => { const mainJsx = import.meta.dirname + "/testdata/main.jsx"; diff --git a/tests/link_jsr_entrypoint/main.test.ts b/tests/link_jsr_entrypoint/main.test.ts new file mode 100644 index 0000000..6de65c8 --- /dev/null +++ b/tests/link_jsr_entrypoint/main.test.ts @@ -0,0 +1,26 @@ +import { + assertResponseText, + createLoader, + ResolutionMode, +} from "../helpers.ts"; + +Deno.test("loads linked entrypoint", async () => { + const mainFile = import.meta.dirname + "/testdata/main/main.ts"; + const { loader } = await createLoader({ + configPath: import.meta.dirname + "/testdata/main/deno.json", + }, { + entrypoints: [mainFile, "jsr:@denotest/add", "@denotest/add"], + }); + + const response = await loader.load( + loader.resolve("@denotest/add", undefined, ResolutionMode.Import), + ); + assertResponseText( + response, + `export function add(a, b) { + return a + b; +} +`, + { skipSourceMap: true }, + ); +}); diff --git a/tests/link_jsr_entrypoint/testdata/add/deno.json b/tests/link_jsr_entrypoint/testdata/add/deno.json new file mode 100644 index 0000000..40e4179 --- /dev/null +++ b/tests/link_jsr_entrypoint/testdata/add/deno.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/add", + "exports": "./mod.ts" +} diff --git a/tests/link_jsr_entrypoint/testdata/add/mod.ts b/tests/link_jsr_entrypoint/testdata/add/mod.ts new file mode 100644 index 0000000..3b39966 --- /dev/null +++ b/tests/link_jsr_entrypoint/testdata/add/mod.ts @@ -0,0 +1,3 @@ +export function add(a: number, b: number) { + return a + b; +} diff --git a/tests/link_jsr_entrypoint/testdata/main/deno.json b/tests/link_jsr_entrypoint/testdata/main/deno.json new file mode 100644 index 0000000..51c4f91 --- /dev/null +++ b/tests/link_jsr_entrypoint/testdata/main/deno.json @@ -0,0 +1,5 @@ +{ + "links": [ + "../add" + ] +} diff --git a/tests/link_jsr_entrypoint/testdata/main/main.ts b/tests/link_jsr_entrypoint/testdata/main/main.ts new file mode 100644 index 0000000..1ca6314 --- /dev/null +++ b/tests/link_jsr_entrypoint/testdata/main/main.ts @@ -0,0 +1,3 @@ +import { add } from "@denotest/add"; + +console.log(add(1, 2));