1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-21 23:04:45 -05:00

fix: Make npm packages works with import maps (#16754)

Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
Bartek Iwańczuk 2022-11-22 20:09:30 +01:00 committed by GitHub
parent f077c4f248
commit b70f520ebc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 5 deletions

View file

@ -32,8 +32,12 @@ impl NpmPackageReference {
}
pub fn from_str(specifier: &str) -> Result<NpmPackageReference, AnyError> {
let original_text = specifier;
let specifier = match specifier.strip_prefix("npm:") {
Some(s) => s,
Some(s) => {
// Strip leading slash, which might come from import map
s.strip_prefix('/').unwrap_or(s)
}
None => {
// don't allocate a string here and instead use a static string
// because this is hit a lot when a url is not an npm specifier
@ -65,7 +69,12 @@ impl NpmPackageReference {
let sub_path = if parts.len() == name_parts.len() {
None
} else {
Some(parts[name_part_len..].join("/"))
let sub_path = parts[name_part_len..].join("/");
if sub_path.is_empty() {
None
} else {
Some(sub_path)
}
};
if let Some(sub_path) = &sub_path {
@ -79,6 +88,14 @@ impl NpmPackageReference {
}
}
if name.is_empty() {
let msg = format!(
"Invalid npm specifier '{}'. Did not contain a package name.",
original_text
);
return Err(generic_error(msg));
}
Ok(NpmPackageReference {
req: NpmPackageReq { name, version_req },
sub_path,
@ -631,6 +648,54 @@ mod tests {
.to_string(),
"Not a valid package: @package"
);
// should parse leading slash
assert_eq!(
NpmPackageReference::from_str("npm:/@package/test/sub_path").unwrap(),
NpmPackageReference {
req: NpmPackageReq {
name: "@package/test".to_string(),
version_req: None,
},
sub_path: Some("sub_path".to_string()),
}
);
assert_eq!(
NpmPackageReference::from_str("npm:/test").unwrap(),
NpmPackageReference {
req: NpmPackageReq {
name: "test".to_string(),
version_req: None,
},
sub_path: None,
}
);
assert_eq!(
NpmPackageReference::from_str("npm:/test/").unwrap(),
NpmPackageReference {
req: NpmPackageReq {
name: "test".to_string(),
version_req: None,
},
sub_path: None,
}
);
// should error for no name
assert_eq!(
NpmPackageReference::from_str("npm:/")
.err()
.unwrap()
.to_string(),
"Invalid npm specifier 'npm:/'. Did not contain a package name."
);
assert_eq!(
NpmPackageReference::from_str("npm://test")
.err()
.unwrap()
.to_string(),
"Invalid npm specifier 'npm://test'. Did not contain a package name."
);
}
#[test]

View file

@ -1,5 +1,6 @@
{
"imports": {
"chalk": "npm:chalk@5"
"chalk": "npm:chalk@5",
"@denotest/": "npm:/@denotest/dual-cjs-esm/"
}
}

View file

@ -1,7 +1,10 @@
import chalk from "chalk";
import { getSubPathKind } from "@denotest/subpath/main.mjs";
console.log(chalk.green("chalk import map loads"));
export function test(value) {
return chalk.red(value);
}
console.log(getSubPathKind());

View file

@ -1,3 +1,6 @@
Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm
Download http://localhost:4545/npm/registry/chalk
Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm/1.0.0.tgz
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
chalk import map loads
esm

View file

@ -90846,7 +90846,7 @@ var ts;
if (!text.startsWith("npm:")) {
throw new Error("Not an npm specifier: ".concat(text));
}
text = text.replace(/^npm:/, "");
text = text.replace(/^npm:\/?/, "");
var parts = text.split("/");
var namePartLen = text.startsWith("@") ? 2 : 1;
if (parts.length < namePartLen) {
@ -90860,8 +90860,12 @@ var ts;
versionReq = lastNamePart.substring(lastAtIndex + 1);
nameParts[nameParts.length - 1] = lastNamePart.substring(0, lastAtIndex);
}
var name = nameParts.join("/");
if (name.length === 0) {
throw new Error("Npm specifier did not have a name: ".concat(text));
}
return {
name: nameParts.join("/"),
name: name,
versionReq: versionReq,
subPath: parts.length > nameParts.length ? parts.slice(nameParts.length).join("/") : undefined,
};