1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -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> { pub fn from_str(specifier: &str) -> Result<NpmPackageReference, AnyError> {
let original_text = specifier;
let specifier = match specifier.strip_prefix("npm:") { 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 => { None => {
// don't allocate a string here and instead use a static string // 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 // 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() { let sub_path = if parts.len() == name_parts.len() {
None None
} else { } 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 { 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 { Ok(NpmPackageReference {
req: NpmPackageReq { name, version_req }, req: NpmPackageReq { name, version_req },
sub_path, sub_path,
@ -631,6 +648,54 @@ mod tests {
.to_string(), .to_string(),
"Not a valid package: @package" "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] #[test]

View file

@ -1,5 +1,6 @@
{ {
"imports": { "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 chalk from "chalk";
import { getSubPathKind } from "@denotest/subpath/main.mjs";
console.log(chalk.green("chalk import map loads")); console.log(chalk.green("chalk import map loads"));
export function test(value) { export function test(value) {
return chalk.red(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/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 Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
chalk import map loads chalk import map loads
esm

View file

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