diff --git a/src/graph.rs b/src/graph.rs index 379f66aaa..95eab403d 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -2945,6 +2945,12 @@ struct PendingInfo { redirects: BTreeMap, result: Result, Arc>, maybe_version_info: Option, + loaded_package_via_https_url: Option, +} + +struct LoadedJsrPackageViaHttpsUrl { + nv: PackageNv, + manifest_checksum: String, } type PendingInfoFuture<'a> = LocalBoxFuture<'a, PendingInfo>; @@ -3186,7 +3192,15 @@ impl<'a, 'graph> Builder<'a, 'graph> { result, redirects, maybe_version_info, + loaded_package_via_https_url, }) => { + if let Some(pkg) = loaded_package_via_https_url { + self + .graph + .packages + .ensure_package(pkg.nv, pkg.manifest_checksum); + } + for (from, to) in redirects { self.add_redirect(from, to); } @@ -3803,6 +3817,7 @@ impl<'a, 'graph> Builder<'a, 'graph> { })), redirects: BTreeMap::new(), maybe_version_info: Some(version_info), + loaded_package_via_https_url: None, }, response => PendingInfo { specifier, @@ -3832,6 +3847,7 @@ impl<'a, 'graph> Builder<'a, 'graph> { Err(err) => Err(Arc::new(err)), }, maybe_version_info: Some(version_info), + loaded_package_via_https_url: None, }, } } @@ -4135,6 +4151,7 @@ impl<'a, 'graph> Builder<'a, 'graph> { load_specifier: ModuleSpecifier, mut maybe_checksum: Option, maybe_version_info: &mut Option, + loaded_package_via_https_url: &mut Option, redirects: &mut BTreeMap, maybe_version_load_fut: Option<(PackageNv, PendingResult)>, is_dynamic: bool, @@ -4142,14 +4159,19 @@ impl<'a, 'graph> Builder<'a, 'graph> { jsr_url_provider: &dyn JsrUrlProvider, ) -> Result, Arc> { if let Some((package_nv, fut)) = maybe_version_load_fut { + let inner = fut.await?; let info = JsrPackageVersionInfoExt { base_url: jsr_url_provider.package_url(&package_nv), - inner: fut.await?.info, + inner: inner.info, }; if let Some(sub_path) = info.get_subpath(&load_specifier) { maybe_checksum = Some(LoaderChecksum::new(info.get_checksum(sub_path)?.to_string())); } maybe_version_info.replace(info); + loaded_package_via_https_url.replace(LoadedJsrPackageViaHttpsUrl { + nv: package_nv, + manifest_checksum: inner.checksum, + }); } let mut load_specifier = load_specifier; for _ in 0..=loader.max_redirects() { @@ -4190,11 +4212,13 @@ impl<'a, 'graph> Builder<'a, 'graph> { content, specifier, maybe_headers, - } => {return Ok(Some(PendingInfoResponse::Module { - content_or_module_info: ContentOrModuleInfo::Content(content), - specifier, - maybe_headers, - }))}, + } => { + return Ok(Some(PendingInfoResponse::Module { + content_or_module_info: ContentOrModuleInfo::Content(content), + specifier, + maybe_headers, + })) + }, }, Ok(None) => return Ok(None), Err(err) => return Err(Arc::new(err)), @@ -4205,10 +4229,12 @@ impl<'a, 'graph> Builder<'a, 'graph> { } let mut redirects = BTreeMap::new(); + let mut loaded_package_via_https_url = None; let result = try_load_with_redirects( load_specifier, maybe_checksum, &mut maybe_version_info, + &mut loaded_package_via_https_url, &mut redirects, maybe_version_load_fut, is_dynamic, @@ -4222,6 +4248,7 @@ impl<'a, 'graph> Builder<'a, 'graph> { redirects, result, maybe_version_info, + loaded_package_via_https_url, } } .boxed_local(); diff --git a/tests/specs/graph/jsr/import_via_https.txt b/tests/specs/graph/jsr/import_via_https_valid_checksum.txt similarity index 99% rename from tests/specs/graph/jsr/import_via_https.txt rename to tests/specs/graph/jsr/import_via_https_valid_checksum.txt index a3fa57168..8e238b35e 100644 --- a/tests/specs/graph/jsr/import_via_https.txt +++ b/tests/specs/graph/jsr/import_via_https_valid_checksum.txt @@ -13,6 +13,7 @@ } } } + # https://jsr.io/@scope/a/1.0.0/mod.ts export class Test {} diff --git a/tests/specs/graph/jsr/import_via_https_with_deps.txt b/tests/specs/graph/jsr/import_via_https_with_deps.txt new file mode 100644 index 000000000..ece61b313 --- /dev/null +++ b/tests/specs/graph/jsr/import_via_https_with_deps.txt @@ -0,0 +1,126 @@ +# https://jsr.io/@scope/a/meta.json +{"versions": { "1.0.0": {} } } + +# https://jsr.io/@scope/a/1.0.0_meta.json +{ + "exports": { + ".": "./mod.ts" + } +} + +# https://jsr.io/@scope/a/1.0.0/mod.ts +import { Test as Other } from "jsr:@scope/b"; +export class Test {} + +# https://jsr.io/@scope/b/meta.json +{"versions": { "1.0.0": {} } } + +# https://jsr.io/@scope/b/1.0.0_meta.json +{ + "exports": { + ".": "./mod.ts" + } +} + +# https://jsr.io/@scope/b/1.0.0/mod.ts +export class Test {} + +# mod.ts +import { Test } from "https://jsr.io/@scope/a/1.0.0/mod.ts"; +console.log(Test); + +# output +{ + "roots": [ + "file:///mod.ts" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "https://jsr.io/@scope/a/1.0.0/mod.ts", + "code": { + "specifier": "https://jsr.io/@scope/a/1.0.0/mod.ts", + "span": { + "start": { + "line": 0, + "character": 21 + }, + "end": { + "line": 0, + "character": 59 + } + } + }, + "type": { + "error": "Importing JSR packages via HTTPS specifiers for type checking is not supported for performance reasons. If you would like types, import via a `jsr:` specifier instead or else use a non-statically analyzable dynamic import.\n Importing: https://jsr.io/@scope/a/1.0.0/mod.ts", + "span": { + "start": { + "line": 0, + "character": 21 + }, + "end": { + "line": 0, + "character": 59 + } + } + } + } + ], + "size": 80, + "mediaType": "TypeScript", + "specifier": "file:///mod.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "jsr:@scope/b", + "code": { + "specifier": "jsr:@scope/b", + "span": { + "start": { + "line": 0, + "character": 30 + }, + "end": { + "line": 0, + "character": 44 + } + } + } + } + ], + "size": 67, + "mediaType": "TypeScript", + "specifier": "https://jsr.io/@scope/a/1.0.0/mod.ts" + }, + { + "kind": "esm", + "size": 21, + "mediaType": "TypeScript", + "specifier": "https://jsr.io/@scope/b/1.0.0/mod.ts" + } + ], + "redirects": { + "jsr:@scope/b": "https://jsr.io/@scope/b/1.0.0/mod.ts" + }, + "packages": { + "@scope/b": "@scope/b@1.0.0" + } +} + +jsr deps: { + "@scope/a@1.0.0": [ + "jsr:@scope/b", + ], +} + +Fast check https://jsr.io/@scope/b/1.0.0/mod.ts: + {} + export class Test { + } + --- DTS --- + export declare class Test { + }