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:
parent
f077c4f248
commit
b70f520ebc
5 changed files with 81 additions and 5 deletions
|
@ -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]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"imports": {
|
"imports": {
|
||||||
"chalk": "npm:chalk@5"
|
"chalk": "npm:chalk@5",
|
||||||
|
"@denotest/": "npm:/@denotest/dual-cjs-esm/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
cli/tests/testdata/npm/import_map/main.js
vendored
3
cli/tests/testdata/npm/import_map/main.js
vendored
|
@ -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());
|
||||||
|
|
3
cli/tests/testdata/npm/import_map/main.out
vendored
3
cli/tests/testdata/npm/import_map/main.out
vendored
|
@ -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
|
||||||
|
|
8
cli/tsc/00_typescript.js
vendored
8
cli/tsc/00_typescript.js
vendored
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue