1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00

fix: support windows file specifiers with import maps (#11551)

This commit is contained in:
David Sherret 2021-07-29 15:20:34 -04:00 committed by GitHub
parent c276b52828
commit eece46f0d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,6 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError;
use deno_core::serde::Serialize;
use deno_core::serde_json;
use deno_core::serde_json::Map;
@ -181,6 +182,32 @@ impl ImportMap {
Some(specifier_key.to_string())
}
fn append_specifier_to_base(
base: &Url,
specifier: &str,
) -> Result<Url, AnyError> {
let mut base = base.clone();
let is_relative_or_absolute_specifier = specifier.starts_with("../")
|| specifier.starts_with("./")
|| specifier.starts_with('/');
// The specifier could be a windows path such as "C:/a/test.ts" in which
// case we don't want to use `join` because it will make the specifier
// the url since it contains what looks to be a uri scheme. To work around
// this, we append the specifier to the path segments of the base url when
// the specifier is not relative or absolute.
if !is_relative_or_absolute_specifier && base.path_segments_mut().is_ok() {
{
let mut segments = base.path_segments_mut().unwrap();
segments.pop_if_empty();
segments.extend(specifier.split('/'));
}
Ok(base)
} else {
Ok(base.join(specifier)?)
}
}
/// Convert provided JSON map to valid SpecifierMap.
///
/// From specification:
@ -380,21 +407,22 @@ impl ImportMap {
}
}
if maybe_address.is_none() {
return Err(ImportMapError::Other(format!(
let resolution_result = maybe_address.as_ref().ok_or_else(|| {
ImportMapError::Other(format!(
"Blocked by null entry for \"{:?}\"",
specifier_key
)));
}
let resolution_result = maybe_address.clone().unwrap();
))
})?;
// Enforced by parsing.
assert!(resolution_result.to_string().ends_with('/'));
let after_prefix = &normalized_specifier[specifier_key.len()..];
let url = match resolution_result.join(after_prefix) {
let url = match ImportMap::append_specifier_to_base(
resolution_result,
after_prefix,
) {
Ok(url) => url,
Err(_) => {
return Err(ImportMapError::Other(format!(
@ -745,4 +773,27 @@ mod tests {
let result = ImportMap::from_json("https://deno.land", json_map);
assert!(result.is_ok());
}
#[test]
fn mapped_windows_file_specifier() {
// from issue #11530
let mut specifiers = SpecifierMap::new();
specifiers.insert(
"file:///".to_string(),
Some(Url::parse("http://localhost/").unwrap()),
);
let resolved_specifier = ImportMap::resolve_imports_match(
&specifiers,
"file:///C:/folder/file.ts",
None,
)
.unwrap()
.unwrap();
assert_eq!(
resolved_specifier.as_str(),
"http://localhost/C:/folder/file.ts"
);
}
}